在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 管理器
編寫(xiě)自定義存儲(chǔ)系統(tǒng)
高級(jí)
編寫(xiě)你的第一個(gè)Django應(yīng)用,第5部分
視圖層
Django管理文檔生成器
編寫(xiě)你的第一個(gè) Django 程序 第3部分
編寫(xiě)你的第一個(gè)Django應(yīng)用,第6部分
模型層
中間件
測(cè)試
數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)優(yōu)化
文件上傳
中間件
驗(yàn)證器
基于類(lèi)的內(nèi)建通用視圖
部署靜態(tài)文件
使用Django認(rèn)證系統(tǒng)
高級(jí)教程:如何編寫(xiě)可重用的應(yīng)用
Model 類(lèi)參考
Django 初探
使用Django輸出PDF
模型的實(shí)例
模型
文件上傳
進(jìn)行原始的sql查詢(xún)
面向程序員
中間件
編寫(xiě)數(shù)據(jù)庫(kù)遷移
TemplateResponse 和 SimpleTemplateResponse
異常
Django中的測(cè)試
基礎(chǔ)
管理器
File對(duì)象
URL調(diào)度器
加密簽名
國(guó)際化和本地化
日志
查詢(xún)集
django-admin 和 manage.py
使用基于類(lèi)的視圖處理表單
聚合
內(nèi)建基于類(lèi)的視圖的API
如何使用會(huì)話(huà)
部署 Django
其它
其它核心功能
高級(jí)
Django中的密碼管理
模型元選項(xiàng)
按需內(nèi)容處理
查找 API 參考
高級(jí)
Django 的快捷函數(shù)
Django 的設(shè)置
Admin
開(kāi)發(fā)過(guò)程
新手入門(mén)
基于類(lèi)的視圖
模型實(shí)例參考
信號(hào)
表單素材 ( <code>Media</code> 類(lèi))
自定義查找
常見(jiàn)的網(wǎng)站應(yīng)用工具
模型
django.contrib.humanize
Django模版語(yǔ)言
點(diǎn)擊劫持保護(hù)
管理操作
編寫(xiě)你的第一個(gè) Django 程序 第2部分
Django安全
模式編輯器
多數(shù)據(jù)庫(kù)
部署
基于類(lèi)的視圖
內(nèi)建的視圖
視圖裝飾器
面向設(shè)計(jì)師
編寫(xiě)視圖
應(yīng)用程序
如何使用WSGI 部署
參考
表單 API
文件儲(chǔ)存API
認(rèn)證
國(guó)際化和本地化
錯(cuò)誤報(bào)告
基礎(chǔ)
基礎(chǔ)
將遺留數(shù)據(jù)庫(kù)整合到Django
教程
Django異常
編寫(xiě)你的第一個(gè) Django 程序 第4部分
遷移
分頁(yè)
重定向應(yīng)用
表單
從零開(kāi)始
為模型提供初始數(shù)據(jù)
設(shè)置
使用Django輸出CSV
關(guān)聯(lián)對(duì)象參考
使用表單
Django 中的用戶(hù)認(rèn)證
快速安裝指南
安全問(wèn)題歸檔
數(shù)據(jù)庫(kù)函數(shù)
編寫(xiě)自定義的django-admin命令
高級(jí)教程
管理文件
格式本地化
基于類(lèi)的通用視圖 —— 索引
安全
系統(tǒng)檢查框架
為Django編寫(xiě)首個(gè)補(bǔ)丁
模板層
Widgets
編寫(xiě)你的第一個(gè) Django 程序 第1部分
執(zhí)行查詢(xún)

管理器

class Manager

管理器是一個(gè)接口,數(shù)據(jù)庫(kù)查詢(xún)操作通過(guò)它提供給django的模型。django應(yīng)用的每個(gè)模型至少擁有一個(gè) 管理器。

管理器類(lèi)的工作方式在 執(zhí)行查詢(xún)文檔中闡述,而這篇文檔涉及了自定義管理器行為的模型選項(xiàng)。

管理器的名字

通常,django為每個(gè)模型類(lèi)添加一個(gè)名為objects的管理器。然而,如果你想將objects用于字段名稱(chēng),或者你想使用其它名稱(chēng)而不是objects訪(fǎng)問(wèn)管理器,你可以在每個(gè)模型類(lèi)中重命名它。在模型中定義一個(gè)值為models.Manager()的屬性,來(lái)重命名管理器。例如:

from django.db import models

class Person(models.Model):
    #...
    people = models.Manager()

使用例子中的模型, Person.objects會(huì)拋出AttributeError異常,而Person.people.all()會(huì)返回一個(gè)包含所有Person對(duì)象的列表。

自定義管理器

在一個(gè)特定的模型中,你可以通過(guò)繼承管理器類(lèi)來(lái)構(gòu)建一個(gè)自定義的管理器,以及實(shí)例化你的自定義管理器。

你有兩個(gè)原因可能會(huì)自己定義管理器:向器類(lèi)中添加額外的方法,或者修改管理器最初返回的查詢(xún)集。

添加額外的管理器方法

為你的模型添加表級(jí)(table-level)功能時(shí),采用添加額外的管理器方法是更好的處理方式。如果要添加行級(jí)功能--就是說(shuō)該功能只對(duì)某個(gè)模型的實(shí)例對(duì)象起作用。在這種情況下,使用 模型方法 比使用自定義的管理器方法要更好。)

自定義的管理器 方法可以返回你想要的任何數(shù)據(jù),而不只是查詢(xún)集。

例如,下面這個(gè)自定義的 管理器提供了一個(gè) with_counts() 方法,它返回所有 OpinionPoll 對(duì)象的列表,而且列表中的每個(gè)對(duì)象都多了一個(gè)名為 num_responses的屬性,這個(gè)屬性保存一個(gè)聚合查詢(xún)(COUNT*)的結(jié)果:

from django.db import models

class PollManager(models.Manager):
    def with_counts(self):
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute("""
            SELECT p.id, p.question, p.poll_date, COUNT(*)
            FROM polls_opinionpoll p, polls_response r
            WHERE p.id = r.poll_id
            GROUP BY p.id, p.question, p.poll_date
            ORDER BY p.poll_date DESC""")
        result_list = []
        for row in cursor.fetchall():
            p = self.model(id=row[0], question=row[1], poll_date=row[2])
            p.num_responses = row[3]
            result_list.append(p)
        return result_list

class OpinionPoll(models.Model):
    question = models.CharField(max_length=200)
    poll_date = models.DateField()
    objects = PollManager()

class Response(models.Model):
    poll = models.ForeignKey(OpinionPoll)
    person_name = models.CharField(max_length=50)
    response = models.TextField()

在這個(gè)例子中,你已經(jīng)可以使用 OpinionPoll.objects.with_counts() 得到所有含有 num_responses屬性的 OpinionPoll對(duì)象。

這個(gè)例子要注意的一點(diǎn)是: 管理器方法可以訪(fǎng)問(wèn) self.model來(lái)得到它所用到的模型類(lèi)。

修改管理器初始的查詢(xún)集

管理器自帶的 查詢(xún)集返回系統(tǒng)中所有的對(duì)象。例如,使用下面這個(gè)模型:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

... Book.objects.all() 語(yǔ)句將返回?cái)?shù)據(jù)庫(kù)中所有的 Book 對(duì)象。

你可以通過(guò)重寫(xiě) Manager.get_queryset() 的方法來(lái)覆蓋 管理器自帶的 查詢(xún)集。get_queryset() 會(huì)根據(jù)你所需要的屬性返回 查詢(xún)集。

例如,下面的模型有兩個(gè) 管理器,一個(gè)返回所有的對(duì)象,另一個(gè)則只返回作者是 Roald Dahl 的對(duì)象:

# First, define the Manager subclass.
class DahlBookManager(models.Manager):
    def get_queryset(self):
        return super(DahlBookManager, self).get_queryset().filter(author='Roald Dahl')

# Then hook it into the Book model explicitly.
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    objects = models.Manager() # The default manager.
    dahl_objects = DahlBookManager() # The Dahl-specific manager.

在這個(gè)簡(jiǎn)單的例子中,Book.objects.all()將返回?cái)?shù)據(jù)庫(kù)中所有的圖書(shū)。而 Book.dahl_objects.all() 只返回作者是 Roald Dahl 的圖書(shū)。

由于 get_queryset() 返回的是一個(gè) 查詢(xún)集 對(duì)象,所以你仍可以對(duì)它使用 filter(), exclude()和其他 查詢(xún)集的方法。所以下面這些例子都是可用的:

Book.dahl_objects.all()
Book.dahl_objects.filter(title='Matilda')
Book.dahl_objects.count()

這個(gè)例子還展示了另外一個(gè)很有意思的技巧:在同一個(gè)模型中使用多個(gè)管理器。你可以隨你所意在一個(gè)模型里面添加多個(gè) Manager() 實(shí)例。下面就用很簡(jiǎn)單的方法,給模型添加通用過(guò)濾器:

例如:

class AuthorManager(models.Manager):
    def get_queryset(self):
        return super(AuthorManager, self).get_queryset().filter(role='A')

class EditorManager(models.Manager):
    def get_queryset(self):
        return super(EditorManager, self).get_queryset().filter(role='E')

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    role = models.CharField(max_length=1, choices=(('A', _('Author')), ('E', _('Editor'))))
    people = models.Manager()
    authors = AuthorManager()
    editors = EditorManager()

在這個(gè)例子中,你使用 Person.authors.all(), Person.editors.all(),以及 Person.people.all(), 都會(huì)得到和名稱(chēng)相符的結(jié)果。

默認(rèn)管理器

如果你使用了自定義 管理器對(duì)象,要注意 Django 中的第一個(gè) 管理器 (按照模型中出現(xiàn)的順序而定) 擁有特殊的地位。Django 會(huì)將模型中定義的管理器解釋為默認(rèn)的 管理器,并且 Django 中的一部分應(yīng)用(包括數(shù)據(jù)備份)會(huì)使用默認(rèn)的管理器,除了前面那個(gè)模型。因此,要決定默認(rèn)的管理器時(shí),要小心謹(jǐn)慎,仔細(xì)考量,這樣才能避免重寫(xiě) get_queryset() 導(dǎo)致無(wú)法正確地獲得數(shù)據(jù)。

使用管理器訪(fǎng)問(wèn)關(guān)聯(lián)對(duì)象

默認(rèn)情況下,在訪(fǎng)問(wèn)相關(guān)對(duì)象時(shí)(例如choice.poll),Django 并不使用相關(guān)對(duì)象的默認(rèn)管理器,而是使用一個(gè)"樸素"管理器類(lèi)的實(shí)例來(lái)訪(fǎng)問(wèn)。這是因?yàn)?Django 要能從關(guān)聯(lián)對(duì)象中獲得數(shù)據(jù),但這些數(shù)據(jù)有可能被默認(rèn)管理器過(guò)濾掉,或是無(wú)法進(jìn)行訪(fǎng)問(wèn)。

如果普通的樸素管理器類(lèi)(django.db.models.Manager)并不適用于你的應(yīng)用,那么你可以通過(guò)在管理器類(lèi)中設(shè)置 use_for_related_fields ,強(qiáng)制 Django 在你的模型中使用默認(rèn)的管理器。這部分內(nèi)容在 下面有 詳細(xì)介紹。

調(diào)用自定義的查詢(xún)集

雖然大多數(shù)標(biāo)準(zhǔn)查詢(xún)集的方法可以從管理器中直接訪(fǎng)問(wèn)到,但是這是一個(gè)例子,訪(fǎng)問(wèn)了定義在自定義 查詢(xún)集上的額外方法,如果你也在管理器上面實(shí)現(xiàn)了它們:

class PersonQuerySet(models.QuerySet):
    def authors(self):
        return self.filter(role='A')

    def editors(self):
        return self.filter(role='E')

class PersonManager(models.Manager):
    def get_queryset(self):
        return PersonQuerySet(self.model, using=self._db)

    def authors(self):
        return self.get_queryset().authors()

    def editors(self):
        return self.get_queryset().editors()

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    role = models.CharField(max_length=1, choices=(('A', _('Author')), ('E', _('Editor'))))
    people = PersonManager()

這個(gè)例子展示了如何直接從管理器 Person.people調(diào)用authors() 和 editors()。

創(chuàng)建管理器

django 1.7 中新增

對(duì)于上面的例子,同一個(gè)方法需要在查詢(xún)集 和 管理器上創(chuàng)建兩份副本,作為替代,QuerySet.as_manager()可以創(chuàng)建一個(gè)管理器的實(shí)例,它擁有自定義查詢(xún)集的方法:

class Person(models.Model):
    ...
    people = PersonQuerySet.as_manager()

通過(guò)QuerySet.as_manager()創(chuàng)建的管理器 實(shí)例,實(shí)際上等價(jià)于上面例子中的PersonManager。

并不是每個(gè)查詢(xún)集的方法都在管理器層面上有意義。比如 QuerySet.delete(),我們有意防止它復(fù)制到管理器 中。

方法按照以下規(guī)則進(jìn)行復(fù)制:

  • 公共方法默認(rèn)被復(fù)制。
  • 私有方法(前面帶一個(gè)下劃線(xiàn))默認(rèn)不被復(fù)制。
  • 帶queryset_only 屬性,并且值為False的方法總是被復(fù)制。
  • 帶 queryset_only 屬性,并且值為T(mén)rue 的方法不會(huì)被復(fù)制。

例如:

class CustomQuerySet(models.QuerySet):
    # Available on both Manager and QuerySet.
    def public_method(self):
        return

    # Available only on QuerySet.
    def _private_method(self):
        return

    # Available only on QuerySet.
    def opted_out_public_method(self):
        return
    opted_out_public_method.queryset_only = True

    # Available on both Manager and QuerySet.
    def _opted_in_private_method(self):
        return
    _opted_in_private_method.queryset_only = False

from_queryset

classmethod from_queryset(queryset_class)

在進(jìn)一步的使用中,你可能想創(chuàng)建一個(gè)自定義管理器和一個(gè)自定義查詢(xún)集。你可以調(diào)用Manager.from_queryset(),它會(huì)返回管理器的一個(gè)子類(lèi),帶有自定義查詢(xún)集所有方法的副本:

class BaseManager(models.Manager):
    def manager_only_method(self):
        return

class CustomQuerySet(models.QuerySet):
    def manager_and_queryset_method(self):
        return

class MyModel(models.Model):
    objects = BaseManager.from_queryset(CustomQueryset)()

你也可以在一個(gè)變量中儲(chǔ)存生成的類(lèi):

CustomManager = BaseManager.from_queryset(CustomQueryset)

class MyModel(models.Model):
    objects = CustomManager()

自定義管理器和模型繼承

類(lèi)繼承和模型管理器兩者之間配合得并不是很好。 管理器一般只對(duì)其定義所在的類(lèi)起作用,在子類(lèi)中對(duì)其繼承絕對(duì)不是一個(gè)好主意。 而且,因?yàn)榈谝粋€(gè) 管理器會(huì)被 Djange 聲明為默認(rèn)的管理器,所以對(duì)默認(rèn)的管理器 進(jìn)行控制是非常必要的。下面就是 Django 如何處理自定義管理器和模型繼承(model inheritance)的:

  • 定義在非抽象基類(lèi)中的管理器是 不會(huì) 被子類(lèi)繼承的。如果你想從一個(gè)非抽象基類(lèi)中重用管理器,只能在子類(lèi)中重定義管理器。 這是因?yàn)檫@種管理器與定義它的模型 綁定得非常緊密,所以繼承它們經(jīng)常會(huì)導(dǎo)致異常的結(jié)果(特別是默認(rèn)管理器運(yùn)行的時(shí)候)。 因此,它們不應(yīng)繼承給子類(lèi)。
  • 定義在抽象基類(lèi)中的管理器總是被子類(lèi)繼續(xù)的,是按 Python 的命名解析順序解析的(首先是子類(lèi)中的命名覆蓋所有的,然后是第一個(gè)父類(lèi)的,以此類(lèi)推)。 抽象類(lèi)用來(lái)提取子類(lèi)中的公共信息和行為,定義公共管理器也是公共信息的一部分。
  • 如果類(lèi)當(dāng)中顯示定義了默認(rèn)管理器,Django 就會(huì)以此做為默認(rèn)管理器;否則就會(huì)從第一個(gè)抽象基類(lèi)中繼承默認(rèn)管理器; 如果沒(méi)有顯式聲明默認(rèn)管理器,那么 Django 就會(huì)自動(dòng)添加默認(rèn)管理器。

如果你想在一組模型上安裝一系列自定義管理器,上面提到的這些規(guī)則就已經(jīng)為你的實(shí)現(xiàn)提供了必要的靈活性。你可以繼承一個(gè)抽象基類(lèi),但仍要自定義默認(rèn)的管理器。例如,假設(shè)你的基類(lèi)是這樣的:

class AbstractBase(models.Model):
    # ...
    objects = CustomManager()

    class Meta:
        abstract = True

如果你在基類(lèi)中沒(méi)有定義管理器,直接使用上面的代碼,默認(rèn)管理器就是從基類(lèi)中繼承的 objects:

class ChildA(AbstractBase):
    # ...
    # This class has CustomManager as the default manager.
    pass

如果你想從 AbstractBase繼承,卻又想提供另一個(gè)默認(rèn)管理器,那么你可以在子類(lèi)中定義默認(rèn)管理器:

class ChildB(AbstractBase):
    # ...
    # An explicit default manager.
    default_manager = OtherManager()

在這個(gè)例子中, default_manager就是默認(rèn)的 管理器。從基類(lèi)中繼承的 objects 管理器仍是可用的。只不過(guò)它不再是默認(rèn)管理器罷了。

最后再舉個(gè)例子,假設(shè)你想在子類(lèi)中再添加一個(gè)額外的管理器,但是很想使用從 AbstractBase繼承的管理器做為默認(rèn)管理器。那么,你不在直接在子類(lèi)中添加新的管理器,否則就會(huì)覆蓋掉默認(rèn)管理器,而且你必須對(duì)派生自這個(gè)基類(lèi)的所有子類(lèi)都顯示指定管理器。 解決辦法就是在另一個(gè)基類(lèi)中添加新的管理器,然后繼承時(shí)將其放在默認(rèn)管理器所在的基類(lèi) 之后。例如:

class ExtraManager(models.Model):
    extra_manager = OtherManager()

    class Meta:
        abstract = True

class ChildC(AbstractBase, ExtraManager):
    # ...
    # Default manager is CustomManager, but OtherManager is
    # also available via the "extra_manager" attribute.
    pass

注意在抽象模型上面定義一個(gè)自定義管理器的時(shí)候,不能調(diào)用任何使用這個(gè)抽象模型的方法。就像:

ClassA.objects.do_something()

是可以的,但是:

AbstractBase.objects.do_something()

會(huì)拋出一個(gè)異常。這是因?yàn)椋芾砥鞅辉O(shè)計(jì)用來(lái)封裝對(duì)象集合管理的邏輯。由于抽象的對(duì)象中并沒(méi)有一個(gè)集合,管理它們是毫無(wú)意義的。如果你寫(xiě)了應(yīng)用在抽象模型上的功能,你應(yīng)該把功能放到抽象模型的靜態(tài)方法,或者類(lèi)的方法中。

實(shí)現(xiàn)上的注意事項(xiàng)

無(wú)論你向自定義管理器中添加了什么功能,都必須可以得到 管理器實(shí)例的一個(gè)淺表副本:例如,下面的代碼必須正常運(yùn)行:

>>> import copy
>>> manager = MyManager()
>>> my_copy = copy.copy(manager)

Django 在一些查詢(xún)中會(huì)創(chuàng)建管理器的淺表副本;如果你的管理器不能被復(fù)制,查詢(xún)就會(huì)失敗。

這對(duì)于大多數(shù)自定義管理器不是什么大問(wèn)題。如果你只是添加一些簡(jiǎn)單的方法到你的管理器中,不太可能會(huì)把你的管理器實(shí)例變?yōu)椴豢蓮?fù)制的。但是,如果你覆蓋了__getattr__,或者其它管理器中控制對(duì)象狀態(tài)的私有方法,你應(yīng)該確保不會(huì)影響到管理器的復(fù)制。

控制自動(dòng)管理器的類(lèi)型

這篇文檔已經(jīng)提到了Django創(chuàng)建管理器類(lèi)的一些位置:默認(rèn)管理器和用于訪(fǎng)問(wèn)關(guān)聯(lián)對(duì)象的“樸素” 管理器。在 Django 的實(shí)現(xiàn)中也有很多地方用到了臨時(shí)的樸素管理器。 正常情況下,django.db.models.Manager 類(lèi)的實(shí)例會(huì)自動(dòng)創(chuàng)建管理器。

在整個(gè)這一節(jié)中,我們將那種由 Django 為你創(chuàng)建的管理器稱(chēng)之為 "自動(dòng)管理器",既有因?yàn)闆](méi)有管理器而被 Django 自動(dòng)添加的默認(rèn)管理器, 也包括在訪(fǎng)問(wèn)關(guān)聯(lián)模型時(shí)使用的臨時(shí)管理器。

有時(shí),默認(rèn)管理器也并非是自動(dòng)管理器。 一個(gè)例子就是 Django 自帶的django.contrib.gis 應(yīng)用,所有 gis模型都必須使用一個(gè)特殊的管理器類(lèi)(GeoManager),因?yàn)樗鼈冃枰\(yùn)行特殊的查詢(xún)集(GeoQuerySet)與數(shù)據(jù)庫(kù)進(jìn)行交互。這表明無(wú)論自動(dòng)管理器是否被創(chuàng)建,那些要使用特殊的管理器的模型仍要使用這個(gè)特殊的管理器類(lèi)。

Django 為自定義管理器的開(kāi)發(fā)者提供了一種方式:無(wú)論開(kāi)發(fā)的管理器類(lèi)是不是默認(rèn)的管理器,它都應(yīng)該可以用做自動(dòng)管理器。 可以通過(guò)在管理器類(lèi)中設(shè)置 use_for_related_fields 屬性來(lái)做到這點(diǎn):

class MyManager(models.Manager):
    use_for_related_fields = True
    # ...

如果在模型中的默認(rèn) 管理器(在這些情況中僅考慮默認(rèn)管理器)中設(shè)置了這個(gè)屬性,那么無(wú)論它是否需要被自動(dòng)創(chuàng)建,Django 都會(huì)自動(dòng)使用它。否則 Django 就會(huì)使用 django.db.models.Manager.

歷史回顧

從它使用目的來(lái)看,這個(gè)屬性的名稱(chēng)(use_for_related_fields)好象有點(diǎn)古怪。原本,這個(gè)屬性?xún)H僅是用來(lái)控制訪(fǎng)問(wèn)關(guān)聯(lián)字段的管理器的類(lèi)型,這就是它名字的由來(lái)。 后來(lái)它的作用更加拓寬了,但是名稱(chēng)一直未變。 因?yàn)橐WC現(xiàn)在的代碼在 Django 以后的版本中仍可以正常工作(continue to work),這就是它名稱(chēng)不變的原因。

在自動(dòng)管理器實(shí)例中編寫(xiě)正確的管理器

在上面的django.contrib.gis 已經(jīng)提到了, use_for_related_fields這個(gè)特性是在需要返回一個(gè)自定義查詢(xún)集子類(lèi)的管理器中使用的。要在你的管理器中提供這個(gè)功能,要注意以下幾點(diǎn)。

不要在這種類(lèi)型的管理器子類(lèi)中過(guò)濾掉任何結(jié)果

一個(gè)原因是自動(dòng)管理器是用來(lái)訪(fǎng)問(wèn)關(guān)聯(lián)模型 的對(duì)象。 在這種情況下,Django 必須要能看到相關(guān)模型的所有對(duì)象,所以才能根據(jù)關(guān)聯(lián)關(guān)系得到任何數(shù)據(jù) 。

如果你重寫(xiě)了 get_queryset() 方法并且過(guò)濾掉了一些行數(shù)據(jù),Django 將返回不正確的結(jié)果。不要這么做! 在 get_queryset()方法中過(guò)濾掉數(shù)據(jù),會(huì)使得它所在的管理器不適于用做自動(dòng)管理器。

設(shè)置 use_for_related_fields

use_for_related_fields屬性必須在管理器類(lèi)中設(shè)置,而不是在類(lèi)的 實(shí)例中設(shè)置。上面已經(jīng)有例子展示如何正確地設(shè)置,下面這個(gè)例子就是一個(gè)錯(cuò)誤的示范:

# BAD: Incorrect code
class MyManager(models.Manager):
    # ...
    pass

# Sets the attribute on an instance of MyManager. Django will
# ignore this setting.
mgr = MyManager()
mgr.use_for_related_fields = True

class MyModel(models.Model):
    # ...
    objects = mgr

# End of incorrect code.

你也不應(yīng)該在模型中使用這個(gè)屬性之后,在類(lèi)上改變它。這是因?yàn)樵谀P皖?lèi)被創(chuàng)建時(shí),這個(gè)屬性值馬上就會(huì)被處理,而且隨后不會(huì)再讀取這個(gè)屬性值。 這節(jié)的第一個(gè)例子就是在第一次定義的時(shí)候在管理器上設(shè)置use_for_related_fields屬性,所有的代碼就工作得很好。