# Dokumentasi Django 5.2.8

# Kerangka contenttypes

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.

## Ikhtisar

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 contenttypes

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 framework` Django menggunakan itu untuk mengikat perizinan pengguna pada model-model tertentu.

## Model `ContentType`

class ContentType

  Setiap instance dari `ContentType` mempunyai dua bidang yang, diambil bersama-sama, secara unik menggambarkan sebuah model terpasang:

  app_label

    Nama dari aplikasi model adalah bagian darinya. Ini diambil dari atribut `app_label` dari model, dan menyertakan hanya bagian terakhir dari `django.contrib.contenttypes` jalur impor Python aplikasi, sebagai contoh, menjadi `app_label` dari `contenttypes`.

  model

    Nama dari kelas model.

  Sebagai tambahan, sifat berikut tersedia:

  name

    Nama dapat-dibaca-manusia dari jenis isi. Ini adalah diambil dari atribut `verbose_name` dari 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:

- `app_label` akan disetel menjadi `'sites'` (bagian terakhir dari jalur Python `django.contrib.sites`).

- `model` akan disetel menjadi `'site'`.

## Metode pada instance `ContentType`

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(using=None, **kwargs)

  Takes a set of valid lookup arguments for the model the `ContentType` represents, and does `a get() lookup` on that model, returning the corresponding object. The `using` argument can be used to specify a different database than the default one.

ContentType.model_class()

  Mengembalikan kelas model diwakilkan oleh instance `ContentType` ini.

For example, we could look up the `ContentType` for the `User` model:

    >>> from django.contrib.contenttypes.models import ContentType
    >>> user_type = ContentType.objects.get(app_label="auth", model="user")
    >>> user_type
    <ContentType: user>

And then use it to query for a particular `User`, or to get access to the `User` model class:

    >>> 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:

1. 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_label` dan `model` kedalam sebuah pencarian `ContentType` pada waktu berjalan dan kemudian bekerja dengan kelas model atau mengambil obyek dari itu.

2. Anda dapat menghubungkan model lain ke `ContentType` sebagai 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".

### `ContentTypeManager`

class ContentTypeManager

  `ContentType` juga mempunyai pengelola penyesuaian, `ContentTypeManager`, yang menambahkan metode berikut:

  clear_cache()

    Bersihkan cache internal digunakan oleh `ContentType` untuk menjaga lintasan dari model-model untuk yang itu telah membuat instance `ContentType`. Anda mungkin tidak pernah butuh memanggil metode ini anda sendiri; Django akan memanggil itu secara otomatis ketika itu dibutuhkan.

  get_for_id(id)

    Pencarian `ContentType` berdasarkan ID. Sejak metode ini menggunakan cache dibagi yang sama seperti `get_for_model()`, itu lebih disukai untuk menggunakan metode ini terhadap `ContentType.objects.get(pk=id)` biasa

  get_for_model(model, for_concrete_model=True)

    Ambil antara sebuah kelas model atau sebuah instance dari model, dan kembalikan instance `ContentType` mewakili model itu. `for_concrete_model=False` mengizinkan mengambil `ContentType` dari model proxy.

  get_for_models(*models, for_concrete_models=True)

    Mengambil sejumlah variabel apapun dari kelas-kelas model, dan mengembalikan sebuah kamus memetakan kelas-kelas model pada instance `ContentType` mewakili mereka. `for_concrete_models=False` mengizinkan mengambil `ContentType` dari model proxy.

  get_by_natural_key(app_label, model)

    Mengembalikan instance `ContentType` secara unik dicirikan dengan label aplikasi yang diberikan dan nama model. Tujuan utama dari metode ini adalah mengizinkan obyek `ContentType` untuk diacukan melalui natural key1 selama deserialisasi.

The `get_for_model()` method is especially useful when you know you need to work with a `ContentType` but don't want to go to the trouble of obtaining the model's metadata to perform a manual lookup:

    >>> from django.contrib.auth.models import User
    >>> ContentType.objects.get_for_model(User)
    <ContentType: user>

## Hubungan umum

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.PositiveBigIntegerField()
        content_object = GenericForeignKey("content_type", "object_id")

        def __str__(self):
            return self.tag

        class Meta:
            indexes = [
                models.Index(fields=["content_type", "object_id"]),
            ]

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 GenericForeignKey

  Terdapat tiga bagian untuk mengatur `GenericForeignKey`:

  1. Berikan model anda sebuah `ForeignKey` pada `ContentType`. Nama biasa untuk bidang ini adalah "content_type".

  2. Give your model a field that can store primary key values from the models you'll be relating to. For most models, this means a `PositiveBigIntegerField`. The usual name for this field is "object_id".

  3. 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 awalan `GenericForeignKey` akan mencari.

  Unlike for the `ForeignKey`, a database index is not automatically created on the `GenericForeignKey`, so it's recommended that you use `Meta.indexes` to add your own multiple column index. This behavior may change in the future.

  for_concrete_model

    Jika `False`, bidang akan dapat mengacukan model-model proxy. Awalan adalah `True`. Ini mencerminkan argumen `for_concrete_model` pada `get_for_model()`.

Kesesuaian jenis primary key

Bidang "object_id" tidak harus mempunyai jenis sama sebagai bidang primary key pada model-model terkait, tetapi nilai-nilai primary key harus dapat dipaksa ke jenis sama sebagai bidang "object_id" dengan metode `get_db_prep_value()` nya.

Sebagai contoh, jika anda ingin mengizinkan hubungan umum pada model-model dengan salah satu primary key `IntegerField` atau `CharField`, anda dapat menggunakan `CharField` untuk bidang "object_id" pada model anda karena integer dapat dipaksa menjadi string oleh `get_db_prep_value()`.

Untuk keluwesan maksimal anda dapat menggunakan `TextField` yang tidak mempunyai panjang maksimal ditentukan, bagaimanapun ini mungkin mendatangkan denda penampilan yang berarti bergantung pada backend basisdata anda.

Tidak ada pemecahan satu-ukuran-cocok-semua untuk jenis bidang yang terbaik. Anda harus menilai model-model anda harapkan untuk ditunjuk dan menentukan pemecahan mana akan menjadi paling efektif untuk penggunaan kasus anda.

Menserialisasikan acuan pada obyek `ContentType`

Jika anda sedang menserialkan data(sebagai contoh, ketika membangkitkan `fixtures`) dari sebuah model yang menerapkan hubungan umum, anda harus mungkin menggunakan kunci alami pada secara unik mencirikan obyek `ContentType` terkait. Lihat natural keys1 and `dumpdata --natural-foreign` untuk informasi lebih.

This will enable an API similar to the one used for a normal `ForeignKey`; each `TaggedItem` will have a `content_object` field that returns the object it's related to, and you can also assign to that field or use it when creating a `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>

If the related object is deleted, the `content_type` and `object_id` fields remain set to their original values and the `GenericForeignKey` returns `None`:

    >>> guido.delete()
    >>> t.content_object  # returns None

Due to the way `GenericForeignKey` is implemented, you cannot use such fields directly with filters (`filter()` and `exclude()`, for example) via the database API. Because a `GenericForeignKey` isn't a normal field object, these examples will not work:

    # This will fail
    >>> TaggedItem.objects.filter(content_object=guido)
    # This will also fail
    >>> TaggedItem.objects.get(content_object=guido)

Likewise, `GenericForeignKey`s do not appear in `ModelForm`s.

### Membalikkan hubungan umum

class GenericRelation
  related_query_name

    Hubungan pada obyek terkait kembali ke obyek ini tidak ada secara awalan. Pengaturan `related_query_name` membuat 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)

`Bookmark` instances will each have a `tags` attribute, which can be used to retrieve their associated `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>]>

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")

This enables filtering, ordering, and other query operations on `Bookmark` from `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 pengumpulan

Django's database aggregation API works with a `GenericRelation`. For example, you can find out how many tags all the bookmarks have:

    >>> Bookmark.objects.aggregate(Count("tags"))
    {'tags__count': 3}

### Hubungan umum di formulir

Modul `django.contrib.contenttypes.forms` menyediakan:

- `BaseGenericInlineFormSet`

- Pabrik formset, `generic_inlineformset_factory()`, untuk digunakan dengan `GenericForeignKey`.

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, absolute_max=None, can_delete_extra=True)

  Mengembalikan `GenericInlineFormSet` menggunakan `modelformset_factory()`.

  Anda harus menyediakan `ct_field` dan `fk_field` jika mereka berbeda dari awalan, `content_type` dan `object_id` masing-masing. Parameter lain adalah mirip ke yang didokumentasi di `modelformset_factory()` dan `inlineformset_factory()`.

  Argumen `for_concrete_model` berhubungan ke argumen `for_concrete_model` pada `GenericForeignKey`.

### Hubungan umum di admin

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 GenericInlineModelAdmin

  Kelas `GenericInlineModelAdmin` mewarisi semua sifat-sifat dari sebuah kelas `InlineModelAdmin`. Bagaimanapun, itu menambahkan sebuah pasang dari itu sendiri untuk bekerja dengan hubungan umum:

  ct_field

    Nama dari bidang foreign key `ContentType` pada model. Awalan pada `content_type`.

  ct_fk_field

    Nama dari bidang integer yang mewakili ID dari obyek terkait. Awalan pada `object_id`.

class GenericTabularInline

class GenericStackedInline

  Subkelas-subkelas dari `GenericInlineModelAdmin` dengan tata letak bertumpuk dan datar, masing-masing.

### `GenericPrefetch()`

class GenericPrefetch(lookup, querysets, to_attr=None)

This lookup is similar to `Prefetch()` and it should only be used on `GenericForeignKey`. The `querysets` argument accepts a list of querysets, each for a different `ContentType`. This is useful for `GenericForeignKey` with non-homogeneous set of results.

    >>> from django.contrib.contenttypes.prefetch import GenericPrefetch
    >>> bookmark = Bookmark.objects.create(url="https://www.djangoproject.com/")
    >>> animal = Animal.objects.create(name="lion", weight=100)
    >>> TaggedItem.objects.create(tag="great", content_object=bookmark)
    >>> TaggedItem.objects.create(tag="awesome", content_object=animal)
    >>> prefetch = GenericPrefetch(
    ...     "content_object", [Bookmark.objects.all(), Animal.objects.only("name")]
    ... )
    >>> TaggedItem.objects.prefetch_related(prefetch).all()
    <QuerySet [<TaggedItem: Great>, <TaggedItem: Awesome>]>