當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Python Django QuerySet.defer用法及代碼示例


本文介紹 django.db.models.query.QuerySet.defer 的用法。

聲明

defer(*fields)

在一些複雜的 data-modeling 情況下,您的模型可能包含很多字段,其中一些可能包含大量數據(例如,文本字段),或者需要進行昂貴的處理才能將它們轉換為 Python 對象。如果您在某些情況下使用查詢集的結果,當您最初獲取數據時不知道是否需要這些特定字段,您可以告訴 Django 不要從數據庫中檢索它們。

這是通過將字段名稱傳遞給不加載到 defer() 來完成的:

Entry.objects.defer("headline", "body")

具有延遲字段的查詢集仍將返回模型實例。如果您訪問該字段(一次一個,而不是一次訪問所有延遲字段),將從數據庫中檢索每個延遲字段。

您可以多次調用 defer() 。每次調用都會將新字段添加到延遲集:

# Defers both the body and headline fields.
Entry.objects.defer("body").filter(rating=5).defer("headline")

將字段添加到延遲集中的順序無關緊要。使用已延遲的字段名稱調用 defer() 是無害的(該字段仍將被延遲)。

您可以通過使用標準 double-underscore 表示法來分隔相關字段來延遲加載相關模型中的字段(如果相關模型通過 select_related() 加載):

Blog.objects.select_related().defer("entry__headline", "entry__body")

如果要清除延遲字段集,請將 None 作為參數傳遞給 defer()

# Load all fields immediately.
my_queryset.defer(None)

模型中的某些字段不會被延遲,即使您要求它們。您永遠不能推遲加載主鍵。如果您使用 select_related() 檢索相關模型,則不應延遲加載從主模型連接到相關模型的字段,這樣做會導致錯誤。

注意

defer() 方法(及其表親, only() ,如下)僅適用於高級 use-cases。當您仔細分析查詢並了解exactly 您需要什麽信息並衡量返回所需字段與模型的完整字段集之間的差異時,它們提供了優化。

即使您認為自己處於高級用例情況,也隻能在無法在查詢集加載時確定是否需要額外字段時才使用 defer()。如果您經常加載和使用數據的特定子集,您可以做出的最佳選擇是將模型標準化並將未加載的數據放入單獨的模型(和數據庫表)中。如果列 must 出於某種原因保留在一個表中,請創建一個帶有 Meta.managed = False 的模型(請參閱 managed attribute 文檔),其中僅包含您通常需要加載的字段並在您可能調用 defer() 的地方使用這些字段.這使您的代碼對讀者更加明確,速度稍快,並且在 Python 進程中消耗的內存更少。

例如,這兩種模型都使用相同的底層數據庫表:

class CommonlyUsedModel(models.Model):
    f1 = models.CharField(max_length=10)

    class Meta:
        managed = False
        db_table = 'app_largetable'

class ManagedModel(models.Model):
    f1 = models.CharField(max_length=10)
    f2 = models.CharField(max_length=10)

    class Meta:
        db_table = 'app_largetable'

# Two equivalent QuerySets:
CommonlyUsedModel.objects.all()
ManagedModel.objects.all().defer('f2')

如果非托管模型中需要複製許多字段,最好創建一個具有共享字段的抽象模型,然後讓非托管和托管模型從抽象模型繼承。

注意

為具有延遲字段的實例調用 save() 時,隻會保存加載的字段。有關詳細信息,請參閱 save()

相關用法


注:本文由純淨天空篩選整理自djangoproject.com大神的英文原創作品 django.db.models.query.QuerySet.defer。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。