Kerangka contenttypesLink to this heading
Django menyertakan sebuah aplikasi contenttypes yang dapat melacak semua model-model terpasang dalam proyek Django-powered anda, menyediakan tingkat-tinggi, antarmuka umum untuk bekerja dengan model-model anda.
IkhtisarLink to this heading
Di jantung dari aplikasi contenttype adalah model ContentType, yang tinggal di django.contrib.contenttypes.models.ContentType`. Instance dari ContentType mewakili dan menyimpan informasi tentang model-model terpasang dalam proyek anda, dan instance baru dari ContentType otomatis dibuat ketika model-model baru terpasang.
Instance dari ContentType mempunai metode-metode untuk mengembalikan kelas-kelas model mereka wakilkan dan untuk meminta obyek dari model-model itu. ContentType juga mempunyai sebuah custom manager 1 yang menambahkan metode untuk bekerja dengan ContentType dan untuk mendapatkan instance dari ContentType untuk model tertentu.
Hubungan diantara model-model anda dan ContentType dapat juga digunakan untuk mengadakan hubungan "umum" diantara sebuah instance dari satu dari model-model anda dan instance dari model apapun anda telah pasang.
Memasang kerangka contenttypesLink to this heading
Kerangka kerja contenttype disertakan dalam daftar INSTALLED_APPS awalan dibuat oleh django-admin startproject, tetapi jika anda telah memindahkan itu atau jika anda secara manual menyetel daftar INSTALLED_APPS anda, anda dapat mengadakan itu dengan menambahkan 'django.contrib.contenttypes' ke pengaturan INSTALLED_APPS anda.
Umumnya ide bagus memiliki kerangka contenttype terpasang; beberapa aplikasi gabungan lain Django membutuhkan itu:
Apliaksi admin menggunakan itu utuk mencatat riwayat dari setiap obyek ditambahkan atau dirubah melalui antarmuka admin.
authentication frameworkDjango menggunakan itu untuk mengikat perizinan pengguna pada model-model tertentu.
Model ContentTypeLink to this heading
- class ContentTypeLink to this definition
Setiap instance dari
ContentTypemempunyai dua bidang yang, diambil bersama-sama, secara unik menggambarkan sebuah model terpasang:- app_labelLink to this definition
Nama dari aplikasi model adalah bagian darinya. Ini diambil dari atribut
app_labeldari model, dan menyertakan hanya bagian terakhir daridjango.contrib.contenttypesjalur impor Python aplikasi, sebagai contoh, menjadiapp_labeldaricontenttypes.
- modelLink to this definition
Nama dari kelas model.
Sebagai tambahan, sifat berikut tersedia:
- nameLink to this definition
Nama dapat-dibaca-manusia dari jenis isi. Ini adalah diambil dari atribut
verbose_namedari model.
Mari kita lihat sebuah contoh untuk melihat bagaimana ini bekerja. Jika anda seudah memiliki aplikasi contenttypes terpasang, dan kemudian tambah the sites application ke pengaturan INSTALLED_APPS anda dan menjalankan manage.py migrate untuk memasangnya, model django.contrib.sites.models.Site akan dipasang kedalam basisdata anda. Bersama dengan itu sebuah instance baru dari ContentType akan dibuat dengan nilai-nilai berikut:
Metode pada instance ContentTypeLink to this heading
Setiap instance ContentType mempunyai metode-metode yang mengizinkan anda mendapatkan dari sebuah instance ContentType pada model yang itu wakili, atau untuk mengambil obyek-obyek dari model itu:
- ContentType.get_object_for_this_type(**kwargs)Link to this definition
Mengambil sekumpulan dari perwakilan lookup arguments 1 for the model the
ContentTypesah, dan melakukana get() lookuppada model itu, mengembalikan obyek yang sesuai.
- ContentType.model_class()Link to this definition
Mengembalikan kelas model diwakilkan oleh instance
ContentTypeini.
Sebagai contoh, kami dapat mencari ContentType untuk model User:
>>> from django.contrib.contenttypes.models import ContentType
>>> user_type = ContentType.objects.get(app_label='auth', model='user')
>>> user_type
<ContentType: user>
Dan kemudian gunakan itu pada permintaan untuk User tertentu, atau untuk mendapatkan akses ke kelas model User:
>>> user_type.model_class()
<class 'django.contrib.auth.models.User'>
>>> user_type.get_object_for_this_type(username='Guido')
<User: Guido>
Bersama-sama, meth:~django.contrib.contenttypes.models.ContentType.get_object_for_this_type dan model_class() mengadakan dua sangat penting penggunaan kasus:
Menggunakan metode ini, anda dapat menulis kode umum tingkat-tinggi yang melakukan permintaan pada mode terpasang apapun -- daripada mengimpor dan menggunakan kelas model khusus, anda dapat melewatkan sebuah
app_labeldanmodelkedalam sebuah pencarianContentTypepada waktu berjalan dan kemudian bekerja dengan kelas model atau mengambil obyek dari itu.Anda dapat menghubungkan model lain ke
ContentTypesebagai sebuah cara dari mengikat instance dari itu ke kelas-kelas model tertentu, dan gunakan metode ini untuk mendapatkan akses ke kelas-kelas model tersebut.
Beberapa dari aplikasi gabungan Django membuat dari teknik terakhir. Sebagai contoh, the permissions system dalam kerangka kerja autentifikasi Django menggunakan model Permission dengan sebuah foreign key pada ContentType; ini membuat Permission mewakili konsep-konsep seperti "dapat menambah masukan blog" atau "dapat menghapus cerita berita".
ContentTypeManagerLink to this heading
- class ContentTypeManagerLink to this definition
ContentTypejuga mempunyai pengelola penyesuaian,ContentTypeManager, yang menambahkan metode berikut:- clear_cache()Link to this definition
Bersihkan cache internal digunakan oleh
ContentTypeuntuk menjaga lintasan dari model-model untuk yang itu telah membuat instanceContentType. Anda mungkin tidak pernah butuh memanggil metode ini anda sendiri; Django akan memanggil itu secara otomatis ketika itu dibutuhkan.
- get_for_id(id)Link to this definition
Pencarian
ContentTypeberdasarkan ID. Sejak metode ini menggunakan cache dibagi yang sama sepertiget_for_model(), itu lebih disukai untuk menggunakan metode ini terhadapContentType.objects.get(pk=id)biasa
- get_for_model(model, for_concrete_model=True)Link to this definition
Ambil antara sebuah kelas model atau sebuah instance dari model, dan kembalikan instance
ContentTypemewakili model itu.for_concrete_model=Falsemengizinkan mengambilContentTypedari model proxy.
- get_for_models(*models, for_concrete_models=True)Link to this definition
Mengambil sejumlah variabel apapun dari kelas-kelas model, dan mengembalikan sebuah kamus memetakan kelas-kelas model pada instance
ContentTypemewakili mereka.for_concrete_models=Falsemengizinkan mengambilContentTypedari model proxy.
- get_by_natural_key(app_label, model)Link to this definition
Mengembalikan instance
ContentTypesecara unik dicirikan dengan label aplikasi yang diberikan dan nama model. Tujuan utama dari metode ini adalah mengizinkan obyekContentTypeuntuk diacukan melalui natural key1 selama deserialisasi.
Metode get_for_model() khususnya sangat berguna ketika anda mengetahui anda butuh bekerja dengan ContentType tetapi tidak ingin menjadi masalah dari mendapatkan metadata model untuk melakukan pencarian manual:
>>> from django.contrib.auth.models import User
>>> ContentType.objects.get_for_model(User)
<ContentType: user>
Hubungan umumLink to this heading
Menambahkan sebuah foreign key dari satu dari model anda sendiri pada ContentType mengizinkan model anda secara efektif mengikat diri sendiri ke kelas model lain, seperti dalam contoh dari model Permission diatas. Tetapi itu memungkinkan pergi satu langkah lebih jauh dan menggunakan ContentType untuk mengadakan hubungan umum sebenarnya (terkadang disebut "polimorfik") diantara model.
Sebagai contoh, itu dapat digunakan untuk sistem pe etiketan seperti itu:
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
Sebuah ForeignKey biasa dapat hanya "menunjuk" satu model lain, yang berarti bahwa jika model TaggedItem menggunakan sebuah ForeignKey itu akan harus memilih satu dan hanya satu model untuk menyimpan etiket-etiket. Aplikasi contenttype menyediakan jenis bidang khusus (GenericForeignKey) yang memecahkan ini dan mengizinkan hubungan dengan model apapun.
- class GenericForeignKeyLink to this definition
Terdapat tiga bagian untuk mengatur
GenericForeignKey:Berikan model anda sebuah
ForeignKeypadaContentType. Nama biasa untuk bidang ini adalah "content_type".Berikan model anda sebuah bidang yang dapat menyimpan nilai-nilai primary key dari model-model anda akan kaitkan. Untuk kebanyakan model, ini berarti
PositiveIntegerField. Nama biasa untuk bidang ini adalah "object_id".Berikan model anda
GenericForeignKey, dan lewatkan itu nama-nama dari dua bidang digambarkan diatas. Jika bidang-bidang ini bernama "content_type" dan "object_id", anda dapat mengabaikan ini --yaitu nama-nama bidang awalanGenericForeignKeyakan mencari.
- for_concrete_modelLink to this definition
Jika
False, bidang akan dapat mengacukan model-model proxy. Awalan adalahTrue. Ini mencerminkan argumenfor_concrete_modelpadaget_for_model().
Ini akan mengadakan sebuah API mitip pada satu digunakan untuk ForeignKey; biasa setiap TaggedItem akan mempunyai sebuah bidang content_object yang mengembalikan obyek yang terkait dengan, dan anda dapat juga menugaskan ke bidang itu atau menggunakan itu ketika membuat sebuah 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>
Jika obyek terkait dihapus, bidang content_type dan object_id masih menyetel ke nilai aslinya dan GenericForeignKey mengembalikan None:
>>> guido.delete()
>>> t.content_object # returns None
Dikarenakan cara GenericForeignKey diterapkan, anda tidak dapat menggunakan bidang-bidang itu langsung dengan penyaring (filter() dan exclude(), sebagai contoh) melalui API basisdata. Karena GenericForeignKey bukan obyek bisang biasa, contoh-contoh ini akan tidak bekerja:
# This will fail
>>> TaggedItem.objects.filter(content_object=guido)
# This will also fail
>>> TaggedItem.objects.get(content_object=guido)
Juga, GenericForeignKey tidak muncul dalam ModelForm.
Membalikkan hubungan umumLink to this heading
- class GenericRelationLink to this definition
Hubungan pada obyek terkait kembali ke obyek ini tidak ada secara awalan. Pengaturan
related_query_namemembuat sebuah hubungan dari obyek terkait kembali ke satu ini. Ini mengizinkan meminta dan menyaring dari obyek terkait.
Jika anda mengetahui model-model mana anda akan menggunakan paling sering, anda dapat juga menambahkan hubungan umum "reverse" untuk mengadakan sebuah tambahan API. Sebagai contoh:
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
class Bookmark(models.Model):
url = models.URLField()
tags = GenericRelation(TaggedItem)
Instance Bookmark akan setipanya memiliki sebuah atribut tags, yang dapat digunakan untuk mengambil TaggedItems terkait mereka:
>>> 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>]>
You can also use add(), create(), or set() to create
relationships:
>>> t3 = TaggedItem(tag='Web development')
>>> b.tags.add(t3, bulk=False)
>>> b.tags.create(tag='Web framework')
<TaggedItem: Web framework>
>>> b.tags.all()
<QuerySet [<TaggedItem: django>, <TaggedItem: python>, <TaggedItem: Web development>, <TaggedItem: Web framework>]>
>>> b.tags.set([t1, t3])
>>> b.tags.all()
<QuerySet [<TaggedItem: django>, <TaggedItem: Web development>]>
The remove() call will bulk delete the specified model objects:
>>> b.tags.remove(t3)
>>> b.tags.all()
<QuerySet [<TaggedItem: django>]>
>>> TaggedItem.objects.all()
<QuerySet [<TaggedItem: django>]>
The clear() method can be used to bulk delete all related objects for an
instance:
>>> b.tags.clear()
>>> b.tags.all()
<QuerySet []>
>>> TaggedItem.objects.all()
<QuerySet []>
Menentukan GenericRelation dengan kumpulan related_query_name mengizinkan meminta dari obyek terkait:
tags = GenericRelation(TaggedItem, related_query_name='bookmark')
Ini mengadakan penyaring, oengurutan, dan tindakan permintaan lain pada Bookmark dari TaggedItem:
>>> # Get all tags belonging to bookmarks containing `django` in the url
>>> TaggedItem.objects.filter(bookmark__url__contains='django')
<QuerySet [<TaggedItem: django>, <TaggedItem: python>]>
If you don't add the related_query_name, you can do the same types of
lookups manually:
>>> bookmarks = Bookmark.objects.filter(url__contains='django')
>>> bookmark_type = ContentType.objects.get_for_model(Bookmark)
>>> TaggedItem.objects.filter(content_type__pk=bookmark_type.id, object_id__in=bookmarks)
<QuerySet [<TaggedItem: django>, <TaggedItem: python>]>
Sama seperti GenericForeignKey menerima nama-nama dari bidang content-type dan object-ID sebagai argumen, begitu juga GenericRelation; jika model yang mempunyai foreign key umum menggunakan nama bukan-awalan untuk bidang-bidang tersebut, anda harus melewatkan nama-nama dari bidang ketika mengatur sebuah GenericRelation untuk itu. Sebagai contoh, jika model TaggedItem mengacu pada diatas menggunakan bidang bernama content_type_fk dan object_primary_key untuk membuat foreign key umumnya, kemudian GenericRelation kembali ke itu akan butuh ditentukan seperti itu:
tags = GenericRelation(
TaggedItem,
content_type_field='content_type_fk',
object_id_field='object_primary_key',
)
Catat juga, bahwa jika anda menghapus sebuah obyek yang mempunyai sebuah GenericRelation, obyek apapun yang mempunyai GenericForeignKey menunjuk ke itu akan dihapus juga. Dalam contoh diatas, ini berarti bahwa jika sebuah obyek Bookmark dihapus, obyek TaggedItem apapun menunjuk pada itu akan dihapus pada waktu yang sama.
Unlike ForeignKey,
GenericForeignKey does not accept
an on_delete argument to customize this
behavior; if desired, you can avoid the cascade-deletion by not using
GenericRelation, and alternate
behavior can be provided via the pre_delete
signal.
Hubungan umum dan pengumpulanLink to this heading
Django's database aggregation API bekerja dengan GenericRelation. Sebagai contoh, anda dapat menemukan berapa banyak etiket semua bookmark miliki:
>>> Bookmark.objects.aggregate(Count('tags'))
{'tags__count': 3}
Hubungan umum di formulirLink to this heading
Modul django.contrib.contenttypes.forms menyediakan:
Pabrik formset,
generic_inlineformset_factory(), untuk digunakan denganGenericForeignKey.
- class BaseGenericInlineFormSetLink to this definition
- 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, absolute_max=None, can_delete_extra=True)Link to this definition
Mengembalikan
GenericInlineFormSetmenggunakanmodelformset_factory().Anda harus menyediakan
ct_fielddanfk_fieldjika mereka berbeda dari awalan,content_typedanobject_idmasing-masing. Parameter lain adalah mirip ke yang didokumentasi dimodelformset_factory()daninlineformset_factory().Argumen
for_concrete_modelberhubungan ke argumenfor_concrete_modelpadaGenericForeignKey.
Hubungan umum di adminLink to this heading
Modul django.contrib.contenttypes.admin menyediakan GenericTabularInline dan GenericStackedInline (subkelas-subkelas dari GenericInlineModelAdmin)
Kelas-kelas dan fungsi-fungsi ini mengadakan penggunaan hubungan umum di formulir dan admin. Lihat dokumentasi model formset dan admin untuk informasi lebih.
- class GenericInlineModelAdminLink to this definition
Kelas
GenericInlineModelAdminmewarisi semua sifat-sifat dari sebuah kelasInlineModelAdmin. Bagaimanapun, itu menambahkan sebuah pasang dari itu sendiri untuk bekerja dengan hubungan umum:- ct_fieldLink to this definition
Nama dari bidang foreign key
ContentTypepada model. Awalan padacontent_type.
- ct_fk_fieldLink to this definition
Nama dari bidang integer yang mewakili ID dari obyek terkait. Awalan pada
object_id.
- class GenericTabularInlineLink to this definition
- class GenericStackedInlineLink to this definition
Subkelas-subkelas dari
GenericInlineModelAdmindengan tata letak bertumpuk dan datar, masing-masing.