Django中文文檔1.8 https://legacy.gitbook.com/book/wizardforcel/django-chinese-docs-18/detailspython
Contenttypesgit
Contenttypes相關方法數據庫
1.class ContentType[source]django
每個 ContentType 實例有兩個字段,共同來惟一描述一個已經安裝的模型,分別是:緩存
app_labelapp
模型所在的應用的名稱。 這取自模型的 app_label 屬性,並只包括應用的Python 導入路徑的最後的部分。函數
例如,"django.contrib.contenttypes"的 app_label 是"contenttypes".佈局
modelui
模型的類的名稱this
額外屬性:
name[source]
Contenttype 的人類可讀的的名稱。它取之於模型的 verbose_name 屬性.
Changed in Django 1.8:
安裝 contenttypes 應用後,添加 sites應用 到你的 INSTALLED_APPS 設置並運行 manage.py migrate 來安裝它,模型 django.contrib.sites.models.Site 將安裝到你的數據庫中。
同時將建立 ContentType 的一個具備如下值的新實例︰
app_label 將設置爲 'sites' (Python 路徑"django.contrib.sites"的最後部分)。
model 將設置爲 'site' 。
2.`get_object_for_this_type (**kwargs)[source]
接收 ContentType 表示的模型所接收的查詢參數,對該模型作 一次get() 查詢 ,而後返回相應的對象
3.model_class ()[source]
返回此 ContentType 實例所表示的模型類。
例如,咱們能夠查找 User 模型的 ContentType ︰
>>> from django.contrib.contenttypes.models import ContentType
>>> user_type = ContentType.objects.get(app_label="auth", model="user")
>>> user_type
<ContentType: user>
而後使用它來查詢一個特定的 User ,或者訪問 User 模型類︰
>>> user_type.model_class() <class 'django.contrib.auth.models.User'> >>> user_type.get_object_for_this_type(username='Guido') <User: Guido>
get_object_for_this_type() 和 model_class() 一塊兒使用能夠實現兩個極其重要的功能
1. 使用這些方法,你能夠編寫高級別的泛型代碼,執行查詢任何已安裝的模型—— 而不是導入和使用單一特定模型的類,能夠經過 app_label 和 model到 ContentType 在運行時查找,而後使用這個模型類或從它獲取對象。
2. 你能夠關聯另外一個模型到 ContentType 做爲一種綁定它到特定模型類的方式,而後使用這些方法來獲取對那些模型的訪問。
4.ContentTypeManager
class ContentTypeManager [source]
ContentType 還具備自定義的管理器 ContentTypeManager ,它增長了下列方
1.get_for_id (id)
代替:ContentType.objects.get(pk=id)
緣由:此方法使用與 get_for_model() 有相同的共享緩存
2.get_for_model(model[, for_concrete_model=True])
接收一個模型類或模型的實例,並返回表示該模型的 ContentType 實例。 for_concrete_model=False 容許獲取代理模型的 ContentType 。
3.get_for_models (*models[, for_concrete_models=True])
接收可變數目的模型類,並返回一個字典,將模型類映射到表示它們的 ContentType 實例。 for_concrete_model=False 容許獲取代理模型的 ContentType 。
4.clear_cache ()[source]
清除 ContentType 用於跟蹤模型的內部緩存,它已爲其建立 ContentType 實例。你可能不須要本身調用此方法;Django 將在它須要的時候自動調用。
5.get_by_natural_key (app_label, model)[source]
返回由給定的應用標籤和模型名稱惟一標識的 ContentType 實例。這種方法的主要目的是爲容許 ContentType 對象在反序列化期間經過天然鍵來引用。
get_for_model() 方法特別有用,當你知道你須要與 ContentType 交互但不想要去獲取模型元數據以執行手動查找的麻煩。
>>> from django.contrib.auth.models import User >>> user_type = ContentType.objects.get_for_model(User) >>> user_type <ContentType: user>
通用關係
在你的model添加一個外鍵到 ContentType 這將容許你更快捷的綁定自身到其餘的model class,就像上述的 Permission model 同樣。
可是它很是有可能進一步的利用 ContentType 來實現真正的 generic (有時稱之爲多態) relationships 在models之間。
一個簡單的例子是標記系統,它可能看起來像這樣:
from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType class TaggedItem(models.Model): tag = models.SlugField() content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') def __str__(self): # __unicode__ on Python 2 return self.tag
一個普通的 ForeignKey 只能指向其餘任意一個model,這是由於TaggedItem model用一個 ForeignKey只能關聯一個model,也只能有一個model存儲tags.
contenttypes application 提供了一個特殊的字段(GenericForeignKey)避免了這個問題,而且容許你和任何一個model創建關聯關係
class GenericForeignKey[source]
三步創建GenericForeignKey:
1.給你的model設置一個ForeignKey字段到ContentType.通常命名爲:「content_type」.
2.給你的model設置一個字段,用來存儲你想要關聯的model主鍵值。對於大多數model,這是一個 PositiveIntegerField字段。而且一般命名爲「object_id」.
3.給你的model一個 GenericForeignKey字段,把1,2點提到的那兩個字段的名詞傳給他。若是這兩個字段名字分別爲「content_type」和「object_id」,你就能夠省略他們。由於GenericForeignKey默認會去自動查找這兩個字段。
for_concrete_model
默認是 True .
若是爲 False ,那麼字段將會涉及到proxy models(代理模型)。
這映射了 for_concrete_model 的參數到 get_for_model() .
allow_unsaved_instance_assignme
New in Django 1.8.
與 ForeignKey.allow_unsaved_instance_assignment 相似。
自1.7版起已棄用:
此類過去在 django.contrib.contenttypes.generic 中定
義。將從Django 1.9中刪除今後舊位置導入的支持。
主鍵類型的兼容性
「object_id」 字段並不老是相同的,這是因爲儲存在相關模型中的主鍵類型的關係,但
是他們的主鍵值必須被轉變爲相同類型。
經過 「object_id」 字段 的get_db_prep_value() 方法實現。
例如, 若是你想要簡歷generic 關係到一個 IntegerField 或者 CharField 爲主
鍵的模型, 你可使用 CharField 給 「object_id」字段,由於數字是能夠被
get_db_prep_value() 轉化爲字母的
序列化 ContentType 的對象引用
若是你想要序列化一個創建了 generic關係的model數據(for example, whengenerating fixtures ) ,你應該用一個天然鍵來惟一的標識相關的ContentType 對象。有關詳細信息,請參閱natural keys和 dumpdata --natural-foreign 。
這容許你像平時用 ForeignKey 相似的API來工做。每個 TaggedItem 都將有一個 content_object 字段返回對象的關聯,你也能夠指定這個字段或者用它來建立一個 TaggedItem :
>>> from django.contrib.auth.models import User >>> guido = User.objects.get(username='Guido') >>> t = TaggedItem(content_object=guido, tag='bdfl') >>> t.save() >>> t.content_object <User: Guido>
因爲 GenericForeignKey 完成的方式問題,,你沒有辦法用這個字段直接執行數據庫API,filters的操做。
好比 ( filter() and exclude() , for example) 。由於一個 GenericForeignKey 不是一個普通的字段對象t, 這些例子是不會工做的:
# This will fail >>> TaggedItem.objects.filter(content_object=guido) # This will also fail >>> TaggedItem.objects.get(content_object=guido)
一樣的, GenericForeignKey s 是不會出如今 ModelForm S
反向通用關係
class GenericRelation [source]
自1.7版起已棄用:此類過去在 django.contrib.contenttypes.generic 中定義。
將從Django 1.9中刪除今後舊位置導入的支持
related_query_name
New in Django 1.7
默認狀況下,相關對象返回到該對象的關係不存在。設置 related_query_name來建立一個對象從關聯對象返回到對象自身。這容許查詢和篩選相關的對象。
若是你知道你最常用哪一種型號的,你還能夠添加一個「反向」的通用關係,以使其能附加一個附加的API。
class Bookmark(models.Model):
url = models.URLField()
tags = GenericRelation(TaggedItem)
Bookmark 的每一個實例都會有一個 tags 屬性,能夠用來獲取相關的TaggedItems
>>> b = Bookmark(url='https://www.djangoproject.com/')
>>> b.save()
>>> t1 = TaggedItem(content_object=b, tag='django')
>>> t1.save()
>>> t2 = TaggedItem(content_object=b, tag='python')
>>> t2.save()
>>> b.tags.all()[<TaggedItem: django>, <TaggedItem: python>]
New in Django 1.7
定義一個 GenericRelation 伴有 related_query_name 能夠容許從相關聯的對象中查詢。
tags = GenericRelation(TaggedItem, related_query_name='bookmarks’)
這容許你從 TaggedItem 執行過濾篩選, 排序, 和其餘的查詢操做 Bookmark
>>> # Get all tags belonging to books containing `django` in the url
>>> TaggedItem.objects.filter(bookmarks__url__contains='django')
[<TaggedItem: django>, <TaggedItem: python>]
GenericRelation和GenericForeignKey同樣能夠接受以content-type和object-id字段命名的參數。
若是一個model的GenericForeignKey字段使用的不是默認的命名,當你建立一個GenericRelation的時候必定要顯示的傳遞這個字段命名給它。例如:
TaggedItem model關聯到上述所用的字段用content_type_fk 和 object_primary_key兩個名稱來建立一個generic foreignkey,而後就須要這樣定義:
tags = GenericRelation(TaggedItem,
content_type_field='content_type_fk',
object_id_field='object_primary_key')
固然,若是你沒有添加一個反向的關係,你能夠手動作相同類型的查找:
>>> b = Bookmark.objects.get(url='https://www.djangoproject.com/')
>>> bookmark_type = ContentType.objects.get_for_model(b)
>>> TaggedItem.objects.filter(content_type__pk=bookmark_type.id,
... object_id=b.id)
[<TaggedItem: django>, <TaggedItem: python>]
若是一個GenericRelation model在它的GenericForeignKey的ct_field or fk_field 使用了非默認值,例如:
ct_field = "object_pk" , 你就要設置GenericRelation中的ct_field和fk_field:
comments = fields.GenericRelation(Comment, object_id_field="object_pk")
同時請注意,若是你刪除了一個具備 GenericRelation 的對象, 任何以GenericForeignKey 指向他的對象也會被刪除. 在上面的例子中, 若是一個Bookmark 對象被刪除了,任何指向它的 TaggedItem 對象也會被同時刪除.
不一樣於 ForeignKey , GenericForeignKey 並不接受一個 on_delete 參數來控制它的行爲:若是你很是渴望這種可控制行爲,你應該不使用GenericRelation 來避免這種級聯刪除,而且這種行爲控制也能夠經過pre_delete 信號來提供。
通用關係和聚合
Django’s database aggregation API不能與 GenericRelation 配合使用。例如,您可能會試圖嘗試如下操做:
Bookmark.objects.aggregate(Count('tags'))
這是錯誤的。然而generic relation 添加了額外的查詢集過濾來保證正確的內容類型,可是aggregate()方法並無被考慮進來。如今,若是你須要再generic relations 使用聚合,你只能不經過聚合API來計算他們。
Generic relation在表單中的應用
django.contrib.contenttypes.forms 模塊提供:
BaseGenericlnlineFormSet
用於GenericForeignKey的表單工廠,generic_inlineformaset_factory().
class BaseGenericInlineFormSet [source]
自1.7版起已棄用:此類過去在 django.contrib.contenttypes.generic 中定義。將從Django 1.9中刪除今後舊位置導入的支持。
generic_inlineformset_factory (model, form=ModelForm,formset=BaseGenericInlineFormSet,
ct_field="content_type", fk_field="object_id",fields=None,
exclude=None, extra=3, can_order=False, can_delete=True,
max_num = None,formfield_callback=None,validate_max=False,
for_concrete_model = True,min_num= None,validate_min = False)
使用 modelformset_factory() 返回 GenericInlineFormSet.
若是它們分別與默認值, content_type 和 object_id 不一樣,則必須提供 ct_field 和 fk_field 。
其餘參數與 modelformset_factory() 和 inlineformset_factory() 中記錄的參數相似.
for_concrete_model 參數對應於 GenericForeignKey 上的 for_concrete_model 參數。
自1.7版起已棄用:此函數用於在 django.contrib.contenttypes.generic 中定義。
將從Django 1.9中刪除今後舊位置導入的支持。
Changed in Django 1.7:
min_num 和 validate_min.
管理中的通用關係
django.contrib.contenttypes.admin 模塊提供GenericTabularInlineGenericStackedInline(GenericInlineModel的子類別)
這些類和函數確保了generic relations在forms 和 admin的使用。有關詳細信息,請參閱model formset和admin文檔。
class GenericInlineModelAdmin [source]
GenericInlineModelAdmin 類繼承了來自 InlineModelAdmin 類的全部屬性。可是,它添加了一些本身的用於處理通用關係:
ct_field
模型上的ContentType外鍵字段的名稱.默認爲content_type。
ct_fk_field
表示相關對象的ID的整數字段的名稱。默認爲object_id。
自1.7版起已棄用:此類過去在 django.contrib.contenttypes.generic 中定義。將從Django 1.9中刪除今後舊位置導入的支持。
class GenericTabularInline [source]
class GenericStackedInline [source]
GenericInlineModelAdmin 的子類,分別具備堆疊和表格佈局.
自1.7版起已棄用:這些類之前在 django.contrib.contenttypes.generic 中定義。將從Django 1.9中刪除今後舊位置導入的支持.