首頁 > 後端開發 > Python教學 > 了解 Django ORM

了解 Django ORM

Mary-Kate Olsen
發布: 2024-10-08 20:11:02
原創
498 人瀏覽過

Understanding Django ORM

什麼是 ORM?

物件關聯映射(ORM)是 Django 中的一項功能,它允許我們使用 Python 程式碼與資料庫交互,而無需編寫 SQL 查詢。 ORM 在底層將 CRUD 操作轉換為 SQL,因此可以輕鬆建立、擷取、更新和刪除資料庫物件。

使用 ORM

在 Django 中,模型類別代表資料庫表,該類別的實例代表表中的一筆記錄。

每個模型至少有一個Manager,稱為物件。我們可以透過這個管理器從資料庫中檢索記錄,從而產生一個 QuerySet

查詢集是惰性的,這表示在明確請求之前不會取得結果。

常用的 QuerySet 方法
filter():檢索符合特定條件的記錄。
all(): 檢索所有記錄。
order_by():根據特定欄位對記錄進行排序。
unique():傳回唯一記錄。
annotate():為每筆記錄新增聚合值。
aggregate():從查詢集中計算一個值。
defer():僅載入模型的某些字段,延遲其他字段。

進階 ORM 功能

Q 和 F 物件 允許複雜的查詢和高效的資料庫層級操作。對於涉及 OR 條件的查詢,我們可以使用“Q”,而“F”則允許您在查詢中直接引用模型欄位。

from django.db.models import Q, F

# Using Q to filter published posts or created after a specific date
posts = Post.objects.filter(Q(status='published') | Q(created_at__gte='2024-01-01'))

# Using F to compare fields within a model (e.g., for a discount calculation)
class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    discounted_price = models.DecimalField(max_digits=10, decimal_places=2)

# Retrieve products where discounted price is less than price
discounted_products = Product.objects.filter(discounted_price__lt=F('price'))
登入後複製

查詢表達式(引用模型欄位)和資料庫函數(應用類似SQL的函數)都允許我們在資料庫層級執行操作,而不是將資料拉入Python進行處理。這有助於優化查詢並減少資料庫負載。

from django.db.models import Count, Max

# Count the number of posts for each status
status_count = Post.objects.values('status').annotate(count=Count('id'))

# Get the latest created post
latest_post = Post.objects.aggregate(latest=Max('created_at'))

登入後複製

自訂管理器讓我們新增額外的管理器方法或修改管理器最初傳回的查詢集。

class PublishedManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status='published')

class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()
    status = models.CharField(max_length=50)
    created_at = models.DateTimeField(auto_now_add=True)

    objects = models.Manager()  # Default manager
    published = PublishedManager()  # Custom manager for published posts

# Use the custom manager to get published posts
published_posts = Post.published.all()

登入後複製

ContentType 是一個模型,可用於在模型之間建立通用關係,而無需使用直接外鍵指定它們。常見用例包括需要附加到不同類型模型的註釋或標籤。

from django.contrib.contenttypes.models import ContentType

# Example model for comments
class Comment(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    text = models.TextField()

# Creating a comment for a Post instance
post = Post.objects.get(id=1)
comment = Comment.objects.create(
    content_type=ContentType.objects.get_for_model(Post),
    object_id=post.id,
    text='Great post!'
)
登入後複製

交易將資料庫操作捆綁為一個單元,確保資料一致性。我們可以使用 @transaction.atomic 裝飾器或 transaction.atomic() 上下文管理器將程式碼包裝在事務區塊中。

from django.db import transaction

# Using a transaction block
with transaction.atomic():
    post = Post.objects.create(title='New Post', content='Content here...', status='published')
    # Any other database operations will be part of this transaction
登入後複製

Django 允許在需要彈性的情況下執行原始 SQL 查詢 進行複雜查詢。但需謹慎使用。

from django.db import connection

def get_published_posts():
    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM blog_post WHERE status = %s", ['published'])
        rows = cursor.fetchall()
    return rows
登入後複製

結論

Django 的 ORM 透過提供用於處理模型、管理器和查詢的高階 API 來簡化資料庫互動。了解和利用這些功能可以大大提高您的工作效率和應用程式的效能。

以上是了解 Django ORM的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板