1. 程式人生 > >django官方文件——管理器(資料庫操作介面)

django官方文件——管理器(資料庫操作介面)

控制自動管理器型別

本文已經談了許多 Django 為你建立的管理器類:`預設管理器`_ 和用於 操作關聯物件 的“簡明”管理器。但是 Django 的執行還需要一些其它的簡明管理器。這些自動建立的管理器是 django.db.models.Manager 的例項。

本節我們會使用“自動管理器”來指代 Django 為你建立的管理器。“自動管理器”包括未定義管理器的模型的預設管理器和當操作關聯物件時臨時使用的管理器。

有時候使用預設的管理器不是一個正確的選擇。例如 Django 自帶的 django.contrib.gis 應用中,所有 gis 模型必須使用一個特殊的管理器類( GeoManager

),因為模型需要一個特殊的查詢集( GeoQuerySet )來與資料庫互動。即有時候模型不需要自動建立的管理器,而只使用特定的管理器。

Django 通過設定管理器 use_for_related_fields 屬性來解決這個問題:

class MyManager(models.Manager):
    use_for_related_fields = True

    ...

如果這個屬性在一個模型的 預設 管理器中被設定了(只有在預設管理器中設定才起作用),那麼 Django 就會始終使用這個管理器,否則就會使用 django.db.models.Manager

歷史由來

根據屬性的用途,屬性的名稱( use_for_related_fields )可能看上去比較瑣碎。因為原來,這個屬性只用於控制操作管理器的關聯欄位。當這個屬性的概念逐漸明確後,它的名稱沒有改變。這只是一個初步的情況,在 Django 以後的版本中程式碼還會 持續改進

在自動管理器例項中使用正確的管理器

上文 django.contrib.gix 例子中我們已經建議過, use_for_related_fields 功能主要用於需要返回一個自定義 查詢集 子類的管理器。為了讓管理器有效工作,還有一些要牢記的東西:

在這種管理器子類中不要過濾掉任何結果

一個原因是一個自動管理器是用於操作其它模型的關聯物件的。在這種情況下, Django 必須可以看見獲得的其它所有模型的物件。因此獲得的任何東西都不要過濾掉。

如果你過載了 get_query_set() 方法並且過濾掉了任何資料庫的行,那麼 Django 會返回不正確的結果。所以不要這樣做。一個過濾 get_query_set() 的結果的管理器不適合用作一個自動管理器。

當定義類時應當設定 use_for_related_fields

use_for_related_fields 屬性必須設定在管理器 中,而不是一個類的 例項 中。上文已經舉了一個正確的例子,下面是一個錯誤的例子:

# 錯誤:不正確的程式碼
class MyManager(models.Manager):
    ...

# 在 MyManager 的例項中設定屬性。 Django 會忽略這個設定。
mgr = MyManager()
mgr.use_for_related_fields = True

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

# 錯誤程式碼結束。

你也不應當在類已經在模型中使用之後改變其屬性,因為當模型類被建立後屬性的值就已經被處理並且不可重新讀取。所以應當在管理器類第一次定義時就設定屬性,就象本節開始的例子那樣,這樣才是正確的方法。