Django 2.1 - The contenttypes framework
कंटेंटपाइप फ्रेमवर्क

कंटेंटपाइप फ्रेमवर्क
Django में एक
contenttypes
एप्लिकेशन शामिल है जो आपके Django द्वारा संचालित प्रोजेक्ट में स्थापित सभी मॉडलों को ट्रैक कर सकता है, आपके मॉडल के साथ काम करने के लिए एक उच्च-स्तरीय, सामान्य इंटरफ़ेस प्रदान करता है।
अवलोकन
django.contrib.contenttypes.models.ContentType
एप्लिकेशन के केंद्र में
ContentType
मॉडल है, जो
django.contrib.contenttypes.models.ContentType
पर
django.contrib.contenttypes.models.ContentType
।
ContentType
उदाहरण आपके प्रोजेक्ट में स्थापित मॉडल के बारे में जानकारी का प्रतिनिधित्व करते हैं और संग्रहीत करते हैं, और जब भी नए मॉडल इंस्टॉल किए जाते हैं, तब
ContentType
नए इंस्टेंस स्वचालित रूप से बनाए जाते हैं।
ContentType
उदाहरणों में उन मॉडल से ऑब्जेक्ट को क्वेरी करने के लिए और उनके मॉडल मॉडल वर्गों को वापस करने के तरीके हैं।
ContentType
में एक
कस्टम मैनेजर
भी है जो
ContentType
साथ काम करने के लिए और किसी विशेष मॉडल के लिए
ContentType
इंस्टेंस प्राप्त करने के लिए तरीके जोड़ता है।
आपके मॉडल और
ContentType
के बीच संबंधों का उपयोग आपके किसी मॉडल के उदाहरण और आपके द्वारा इंस्टॉल किए गए किसी भी मॉडल के उदाहरणों के बीच "सामान्य" रिश्तों को सक्षम करने के लिए भी किया जा सकता है।
Contenttypes ढांचे को स्थापित करना
सामग्री की रूपरेखा को
django-admin startproject
द्वारा बनाई गई डिफ़ॉल्ट
INSTALLED_APPS
सूची में शामिल किया गया है, लेकिन यदि आपने इसे हटा दिया है या यदि आपने मैन्युअल रूप से अपनी
INSTALLED_APPS
सूची सेट की है, तो आप अपने
INSTALLED_APPS
'django.contrib.contenttypes'
जोड़कर इसे सक्षम कर सकते हैं। सेटिंग।
यह आमतौर पर एक अच्छा विचार है कि contenttypes फ्रेमवर्क स्थापित किया गया है; Django के अन्य बंडल किए गए अनुप्रयोगों में से कई को इसकी आवश्यकता है:
- व्यवस्थापक एप्लिकेशन इसका उपयोग व्यवस्थापक इंटरफ़ेस के माध्यम से जोड़े गए या बदले गए प्रत्येक ऑब्जेक्ट के इतिहास को लॉग करने के लिए करता है।
-
Django के
authentication framework
का उपयोग उपयोगकर्ता अनुमतियों को विशिष्ट मॉडल से जोड़ने के लिए करता है।
ContentType
मॉडल
-
class ContentType
-
ContentType
प्रत्येक उदाहरण में दो फ़ील्ड होते हैं, जिन्हें एक साथ लिया जाता है, विशिष्ट रूप से एक स्थापित मॉडल का वर्णन करता है:-
app_label
-
मॉडल का उपयोग करने वाले एप्लिकेशन का नाम है। यह मॉडल के
app_label
विशेषता से लिया गया है, और इसमें एप्लिकेशन के पायथन आयात पथ का केवल अंतिम भाग शामिल है; उदाहरण के लिए,app_label
,contenttypes
का एकapp_label
बन जाता है।
-
model
-
मॉडल वर्ग का नाम।
इसके अतिरिक्त, निम्नलिखित संपत्ति उपलब्ध है:
-
name
-
सामग्री प्रकार का मानव-पठनीय नाम। यह मॉडल की
verbose_name
विशेषता से लिया गया है।
-
आइए एक उदाहरण देखें कि यह कैसे काम करता है।
यदि आपके पास पहले से ही
contenttypes
एप्लिकेशन इंस्टॉल है, और फिर अपनी
INSTALLED_APPS
सेटिंग
the sites application
को जोड़ें और इसे इंस्टॉल
manage.py migrate
लिए
manage.py migrate
चलाएं, मॉडल
django.contrib.sites.models.Site
आपके डेटाबेस में इंस्टॉल हो जाएगा।
इसके साथ ही
ContentType
का एक नया उदाहरण निम्नलिखित मानों के साथ बनाया जाएगा:
-
app_label
'sites'
(पायथन पथdjango.contrib.sites
के अंतिम भाग) पर सेट किया जाएगा। -
model
को'site'
सेट किया जाएगा।
ContentType
इंस्टेंस पर विधियाँ
प्रत्येक
ContentType
आवृत्ति में वे विधियाँ होती हैं जो आपको
ContentType
उदाहरण से उस मॉडल को प्राप्त करने की अनुमति देती हैं, जो उस का प्रतिनिधित्व करती है, या उस ऑब्जेक्ट से पुनर्प्राप्त करने के लिए:
-
ContentType.get_object_for_this_type(**kwargs)
-
जिस मॉडल के
ContentType
प्रतिनिधित्व करता है, उसके लिए मान्य लुकअप तर्कों का एक सेट लेता है और संबंधित मॉडल को लौटाता है।
-
ContentType.model_class()
-
इस
ContentType
उदाहरण द्वारा प्रस्तुत मॉडल वर्ग लौटाता है।
उदाहरण के लिए, हम
User
मॉडल के लिए
ContentType
देख सकते हैं:
>>> from django.contrib.contenttypes.models import ContentType >>> ContentType.objects.get(app_label="auth", model="user") <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()
दो अत्यंत महत्वपूर्ण उपयोग मामलों को सक्षम करें:
-
इन विधियों का उपयोग करते हुए, आप उच्च-स्तरीय जेनेरिक कोड लिख सकते हैं जो किसी भी स्थापित मॉडल पर प्रश्न करता है - एक ही विशिष्ट मॉडल वर्ग को आयात और उपयोग करने के बजाय, आप एक
app_label
औरmodel
को रनटाइम पर एकContentType
लुकअप में पास कर सकते हैं, और फिर उसके साथ काम कर सकते हैं मॉडल वर्ग या वस्तुओं को पुनः प्राप्त करना। -
आप किसी अन्य मॉडल को
ContentType
से संबंधित मॉडल वर्गों के लिए विशेष रूप से बांधने के उदाहरण के रूप में संबंधित कर सकते हैं, और उन मॉडल कक्षाओं तक पहुंच प्राप्त करने के लिए इन विधियों का उपयोग कर सकते हैं।
Django के कई बंडल एप्लिकेशन बाद की तकनीक का उपयोग करते हैं।
उदाहरण के लिए, Django के प्रमाणीकरण ढांचे में
the permissions system
ContentType
लिए एक विदेशी कुंजी के साथ एक
Permission
मॉडल का उपयोग करती है;
इससे
Permission
"ब्लॉग प्रविष्टि जोड़ सकते हैं" या "समाचार कहानी हटा सकते हैं" जैसी अवधारणाओं का प्रतिनिधित्व करती है।
ContentTypeManager
-
class ContentTypeManager
-
ContentType
में एक कस्टम मैनेजर भी है,ContentTypeManager
, जो निम्नलिखित तरीके जोड़ता है:-
clear_cache()
-
उन
ContentType
का ट्रैक रखने के लिएContentType
द्वारा उपयोग किए जाने वाले आंतरिक कैश को साफ़ करता है जिसके लिए उसनेContentType
इंस्टेंस बनाए हैं। आपको शायद कभी इस विधि को स्वयं कॉल करने की आवश्यकता नहीं होगी; जरूरत पड़ने पर Django इसे स्वचालित रूप से कॉल करेगा।
-
get_for_id(id)
-
ID द्वारा एक
ContentType
लुकअप करें। चूंकि यह विधि समान साझा कैश का उपयोगget_for_model()
रूप मेंget_for_model()
, इसलिए इस सामग्री को सामान्यContentType.objects.get(pk=id)
से अधिक उपयोग करना पसंद किया जाता है
-
get_for_model(model, for_concrete_model=True)
-
या तो एक मॉडल वर्ग या एक मॉडल का एक उदाहरण लेता है, और उस मॉडल का प्रतिनिधित्व करने वाले
ContentType
उदाहरण देता है।for_concrete_model=False
प्रॉक्सी मॉडल केContentType
को लाने की अनुमति देता है।
-
get_for_models(*models, for_concrete_models=True)
-
मॉडल कक्षाओं की एक विविध संख्या लेता है, और एक मॉडल की मैपिंग करता है जो मॉडल कक्षाओं को कंटेंट टाइप उदाहरणों का प्रतिनिधित्व करता है।
for_concrete_models=False
प्रॉक्सी मॉडल केContentType
को लाने की अनुमति देता है।
-
get_by_natural_key(app_label, model)
-
दिए गए एप्लिकेशन लेबल और मॉडल के नाम से
ContentType
उदाहरण को विशिष्ट रूप से पहचानता है। इस विधि का प्राथमिक उद्देश्यContentType
वस्तुओं कोContentType
दौरान एक प्राकृतिक कुंजी के माध्यम से संदर्भित करने की अनुमति देना है।
-
get_for_model()
विधि विशेष रूप से तब उपयोगी होती है जब आप जानते हैं कि आपको
ContentType
साथ काम करने की आवश्यकता है, लेकिन मैन्युअल लुकअप करने के लिए मॉडल के मेटाडेटा को प्राप्त करने की परेशानी में नहीं जाना चाहते हैं:
>>> from django.contrib.auth.models import User >>> ContentType.objects.get_for_model(User) <ContentType: user>
सामान्य संबंध
अपने स्वयं के मॉडल में से एक से एक विदेशी कुंजी को
ContentType
जोड़ना आपके मॉडल को प्रभावी रूप से खुद को दूसरे मॉडल वर्ग में बाँधने की अनुमति देता है, जैसा कि ऊपर दिए गए
Permission
मॉडल के उदाहरण में है।
लेकिन मॉडल के बीच सही मायने में सामान्य (कभी-कभी "बहुरूपी" कहा जाता है) रिश्तों को सक्षम करने के लिए एक कदम आगे जाना और
ContentType
का उपयोग करना संभव है।
एक सरल उदाहरण एक टैगिंग सिस्टम है, जो इस तरह दिख सकता है:
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models class TaggedItem(models.Model): tag = models.SlugField() content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') def __str__(self): return self.tag
एक सामान्य
ForeignKey
केवल एक अन्य मॉडल के लिए "इंगित" कर सकता है, जिसका अर्थ है कि अगर
TaggedItem
मॉडल ने
TaggedItem
उपयोग किया है, तो इसके लिए टैग स्टोर करने के लिए एक और केवल एक मॉडल चुनना होगा।
GenericForeignKey
एप्लिकेशन एक विशेष फ़ील्ड प्रकार (
GenericForeignKey
) प्रदान करता है जो इसके चारों ओर काम करता है और किसी भी मॉडल के साथ संबंध रखने की अनुमति देता है:
-
class GenericForeignKey
-
एक
GenericForeignKey
स्थापना के लिए तीन भाग हैं:-
अपने मॉडल को
ContentType
ForeignKey
लिए एकForeignKey
दें। इस फ़ील्ड का सामान्य नाम "content_type" है। -
अपने मॉडल को एक ऐसा क्षेत्र दें, जो आपके द्वारा संबंधित मॉडल से प्राथमिक प्रमुख मूल्यों को संग्रहीत कर सकता है।
अधिकांश मॉडलों के लिए, इसका मतलब है एक
PositiveIntegerField
। इस फ़ील्ड का सामान्य नाम "object_id" है। -
अपने मॉडल को एक
GenericForeignKey
दें, और इसे ऊपर वर्णित दो क्षेत्रों के नाम दें। यदि इन फ़ील्ड्स को "content_type" और "object_id" नाम दिया गया है, तो आप इसे छोड़ सकते हैं - वे डिफ़ॉल्ट फ़ील्ड नाम हैंGenericForeignKey
लिएGenericForeignKey
दिखेगा।
-
for_concrete_model
-
यदि
False
, तो फ़ील्ड प्रॉक्सी मॉडल को संदर्भित करने में सक्षम होगी। डिफ़ॉल्टTrue
। यहget_for_model()
लिएget_for_model()
तर्क कोget_for_model()
।
-
अपने मॉडल को
प्राथमिक कुंजी प्रकार संगतता
संबंधित
get_db_prep_value()
फ़ील्ड के समान "
get_db_prep_value()
" फ़ील्ड का प्रकार नहीं होना चाहिए, लेकिन उनके प्राथमिक कुंजी मान उसी प्रकार के लिए समान होना चाहिए जैसे "
get_db_prep_value()
" फ़ील्ड इसके
get_db_prep_value()
विधि द्वारा।
उदाहरण के लिए, यदि आप या तो
IntegerField
या
CharField
प्राथमिक कुंजी फ़ील्ड के साथ मॉडल के लिए सामान्य संबंधों को अनुमति देना चाहते हैं, तो आप अपने मॉडल पर "object_id" फ़ील्ड के लिए
CharField
उपयोग कर सकते हैं क्योंकि पूर्णांक__
get_db_prep_value()
द्वारा स्ट्रिंग्स के लिए
get_db_prep_value()
किए जा सकते हैं।
अधिकतम लचीलेपन के लिए आप एक
TextField
उपयोग कर सकते हैं, जिसकी अधिकतम लंबाई परिभाषित नहीं है, हालांकि यह आपके डेटाबेस के आधार पर महत्वपूर्ण प्रदर्शन दंड को लागू कर सकता है।
कोई एक आकार-फिट-सभी समाधान नहीं है जिसके लिए फ़ील्ड प्रकार सबसे अच्छा है। आपको उन मॉडलों का मूल्यांकन करना चाहिए जिनकी आप इंगित करते हैं और निर्धारित करते हैं कि आपके उपयोग के मामले के लिए कौन सा समाधान सबसे प्रभावी होगा।
कन्टैंट
ContentType
वस्तुओं के संदर्भों को क्रमबद्ध करना
यदि आप डेटा को क्रमबद्ध कर रहे हैं (उदाहरण के लिए,
fixtures
बनाते समय) तो सामान्य संबंधों को लागू करने वाले मॉडल से, आपको संभवतः संबंधित
ContentType
ऑब्जेक्ट्स की विशिष्ट पहचान करने के लिए एक प्राकृतिक कुंजी का उपयोग करना चाहिए।
अधिक जानकारी के लिए
प्राकृतिक कुंजियाँ
और
dumpdata --natural-foreign
देखें।
यह सामान्य
ForeignKey
लिए उपयोग किए जाने वाले एपीआई के समान एपीआई को सक्षम करेगा;
प्रत्येक
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>
यदि संबंधित ऑब्जेक्ट हटा दिया जाता है, तो
content_type
और
object_id
फ़ील्ड उनके मूल मानों पर सेट हो जाते हैं और
GenericForeignKey
None
देता है:
>>> guido.delete() >>> t.content_object # returns None
GenericForeignKey
को लागू करने के तरीके के कारण, आप डेटाबेस API के माध्यम से
filter()
और
exclude()
उदाहरण के लिए) के साथ सीधे ऐसे फ़ील्ड का उपयोग नहीं कर सकते।
क्योंकि
GenericForeignKey
एक सामान्य फ़ील्ड ऑब्जेक्ट नहीं है, ये उदाहरण काम
नहीं
करेंगे:
# This will fail >>> TaggedItem.objects.filter(content_object=guido) # This will also fail >>> TaggedItem.objects.get(content_object=guido)
इसी तरह,
GenericForeignKey
में प्रदर्शित नहीं होता है।
सामान्य संबंधों को उलट दें
-
class GenericRelation
-
-
इस ऑब्जेक्ट पर संबंधित ऑब्जेक्ट का संबंध डिफ़ॉल्ट रूप से मौजूद नहीं है।
related_query_name
सेट करना संबंधित वस्तु से इस पर वापस संबंध बनाता है। यह संबंधित ऑब्जेक्ट से क्वेरी और फ़िल्टरिंग की अनुमति देता है।
-
यदि आप जानते हैं कि कौन से मॉडल आप सबसे अधिक बार उपयोग कर रहे हैं, तो आप अतिरिक्त API सक्षम करने के लिए "रिवर्स" जेनेरिक संबंध भी जोड़ सकते हैं। उदाहरण के लिए:
from django.contrib.contenttypes.fields import GenericRelation from django.db import models 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() <QuerySet [<TaggedItem: django>, <TaggedItem: python>]>
GenericRelation
को
GenericRelation
सेट के साथ परिभाषित करने से संबंधित ऑब्जेक्ट से क्वेरी करने की अनुमति मिलती है:
tags = GenericRelation(TaggedItem, related_query_name='bookmarks')
यह
TaggedItem
से
Bookmark
पर फ़िल्टर करने, ऑर्डर करने और अन्य क्वेरी संचालन को
TaggedItem
:
>>> # Get all tags belonging to bookmarks containing `django` in the url >>> TaggedItem.objects.filter(bookmarks__url__contains='django') <QuerySet [<TaggedItem: django>, <TaggedItem: python>]>
बेशक, यदि आप रिवर्स रिलेशनशिप नहीं जोड़ते हैं, तो आप उसी प्रकार के लुकअप को मैन्युअल रूप से कर सकते हैं:
>>> 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) <QuerySet [<TaggedItem: django>, <TaggedItem: python>]>
जैसे
GenericForeignKey
रूप में सामग्री-प्रकार और ऑब्जेक्ट-आईडी फ़ील्ड के नामों को स्वीकार करता है, वैसे ही
GenericRelation
भी करता है;
यदि जिस मॉडल में जेनेरिक विदेशी कुंजी है, उन क्षेत्रों के लिए गैर-डिफ़ॉल्ट नामों का उपयोग कर रहा है, तो आपको
GenericRelation
सेट करते समय फ़ील्ड के नामों को पास करना होगा।
उदाहरण के लिए, अगर
TaggedItem
मॉडल ने अपनी जेनेरिक विदेशी कुंजी बनाने के लिए
content_type_fk
और
object_primary_key
नामक उपरोक्त उपयोग किए गए फ़ील्ड का उल्लेख किया है, तो एक जेनेरिक
GenericRelation
को इस तरह परिभाषित करने की आवश्यकता होगी:
tags = GenericRelation( TaggedItem, content_type_field='content_type_fk', object_id_field='object_primary_key', )
यह भी ध्यान दें, कि यदि आप
GenericRelation
ऑब्जेक्ट को
GenericRelation
, तो जिन ऑब्जेक्ट्स पर
GenericForeignKey
इंगित होता है, उन्हें भी हटा दिया जाएगा।
ऊपर दिए गए उदाहरण में, इसका मतलब है कि यदि कोई
Bookmark
ऑब्जेक्ट हटा दिया गया है, तो कोई भी इंगित करने वाली ऑब्जेक्टइमेट्स ऑब्जेक्ट उसी समय हटा दिया जाएगा।
ForeignKey
विपरीत,
GenericForeignKey
इस व्यवहार को अनुकूलित करने के लिए
on_delete
तर्क को स्वीकार नहीं करता है;
यदि वांछित है, तो आप
GenericRelation
का उपयोग न करके केवल कैस्केड-विलोपन से बच सकते हैं, और वैकल्पिक व्यवहार को
pre_delete
सिग्नल के माध्यम से प्रदान किया जा सकता है।
सामान्य संबंध और एकत्रीकरण
Django का डेटाबेस एग्रीगेशन एपीआई
एक
GenericRelation
साथ काम करता है।
उदाहरण के लिए, आप यह जान सकते हैं कि सभी बुकमार्क में कितने टैग हैं:
>>> Bookmark.objects.aggregate(Count('tags')) {'tags__count': 3}
रूपों में सामान्य संबंध
django.contrib.contenttypes.forms
मॉड्यूल प्रदान करता है:
-
BaseGenericInlineFormSet
-
generic_inlineformset_factory()
साथ उपयोग के लिए एकgeneric_inlineformset_factory()
फ़ैक्टरी,generic_inlineformset_factory()
-
class BaseGenericInlineFormSet
-
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()
का उपयोग करके एकmodelformset_factory()
लौटाता है।यदि आप क्रमशः चूक,
content_type
औरobject_id
से अलग हैं, तो आपकोct_field
औरfk_field
प्रदान करना होगा। अन्य पैरामीटरmodelformset_factory()
औरinlineformset_factory()
modelformset_factory()
में प्रलेखित के समान हैं।for_concrete_model
तर्कfor_concrete_model
तर्क से मेलGenericForeignKey
।
सामान्य संबंध सामान्य में
django.contrib.contenttypes.admin
मॉड्यूल
GenericTabularInline
और
GenericTabularInline
(
GenericTabularInline
उपवर्ग) प्रदान करता है
ये कक्षाएं और फ़ंक्शंस रूपों और व्यवस्थापक में सामान्य संबंधों के उपयोग को सक्षम करते हैं। अधिक जानकारी के लिए मॉडल फ़ॉर्मेट और admin दस्तावेज़ देखें।
-
class GenericInlineModelAdmin
-
InlineModelAdmin
वर्ग एकInlineModelAdmin
वर्ग से सभी गुण प्राप्त करता है। हालांकि, यह सामान्य संबंध के साथ काम करने के लिए अपने स्वयं के जोड़े को जोड़ता है:-
ct_field
-
मॉडल पर
ContentType
विदेशी कुंजी फ़ील्ड का नाम। Content_type में डिफ़ॉल्ट।
-
ct_fk_field
-
पूर्णांक फ़ील्ड का नाम जो संबंधित ऑब्जेक्ट की आईडी का प्रतिनिधित्व करता है। Object_id के लिए डिफ़ॉल्ट।
-
-
class GenericTabularInline
-
class GenericStackedInline
-
क्रमशः खड़ी और सारणीबद्ध लेआउट के साथ
GenericInlineModelAdmin
उपवर्ग।