# Dokumentasi Django 4.2.9.dev20231204082947

# Model

Sebuah model adalah tunggal, sumber pasti dari informasi tentang data anda. Itu mengandung bidang-bdiang penting dan perilaku dari data anda masih sedang menyimpan. Umumnya, stiap model memetakan pada sebuah tabel basisdata tunggal.

Dasar:

- Setiap model adalah kelas Python yang subkelas `django.db.models.Model`.
- Setiap atribut dari model mewakili bidang basisdata.
- Dengan semua ini, Django memberikan API akses-basisdata dibangkitkan-otomatis; lihat Membuat query.

## Contoh cepat

Model contoh ini menentukan `Person`, yang mempunyai `first_name` dan `last_name`:

    from django.db import models

    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)

`first_name` dan `last_name` adalah fields dari model. Setiap bidang ditentukan sebagai atribut kelas, dan setiap atribut memetakan pada sebuah kolom basisdata.

Model `Person` diatas akan membuat sebuah tabel basisdata seperti ini:

    CREATE TABLE myapp_person (
        "id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
        "first_name" varchar(30) NOT NULL,
        "last_name" varchar(30) NOT NULL
    );

Beberapa catatan teknis:

- Nama dari tabel, `myapp_person`, otomatis berasal dari beberapa metadata model tetapi dapat ditimpa. Lihat Nama tabel untuk rincian lebih.
- Sebuah bidang `id` ditambahkan secara otomatis, tetapi perilaku ini dapat dikesampingkan. Lihat Bidang primary key otomatis.
- SQL `CREATE TABLE` dalam contoh ini dibentuk menggunakan sintaksis PostgreSQL, tetapi itu perlu dicatat Django menggunakan SQL disesuaikan pada backend basisdata ditentukan dalam settings file anda.

## Menggunakan model

Sekali anda telah menentukan model anda, anda butuh memberitahu Django anda sedang akan menggunakan model-model tersebut. Lakukan ini dengan menyunting berkas pengaturan anda dan merubah pengaturan `INSTALLED_APPS` untuk menambah nama dari modul yang mengandung `models.py` anda.

Sebagai contoh, jika model-model untuk aplikasi anda tinggal dalam modul `myapp.models` (struktur paket yang dibuat untuk sebuah aplikasi oleh tulisan `manage.py startapp`), `INSTALLED_APPS` harus membaca, dalam bagian:

    INSTALLED_APPS = [
        # ...
        "myapp",
        # ...
    ]

Ketika anda menambah aplikasi baru pada `INSTALLED_APPS`, pastikan menjalankan `manage.py migrate`, pilihannya membuat perpindahan untuk mereka dahulu dengan `manage.py makemigrations`.

## Bidang

Bagian paling penting dari sebuah model -- dan hanya membutuhkan bagian dari sebah model -- adalah daftar bidang basisdata itu tentukan. Bidang-bidang ditentukan oleh atribut kelas. Hati-hati tidak memilih nama bidang yang bertentangan dengan models API seperti `clean`, `save`, atau `delete`.

Contoh:

    from django.db import models

    class Musician(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        instrument = models.CharField(max_length=100)

    class Album(models.Model):
        artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
        name = models.CharField(max_length=100)
        release_date = models.DateField()
        num_stars = models.IntegerField()

### Jenis bidang

Setiap bidang dalam model anda harus berupa sebuah instance dari kelas `Field` sesuai. Django menggunakan jenis kelas bidang untuk menentukan sedikit hal:

- Jenis kolom, yang memberitahu basisdata maca apa dari data disimpan (sebagai contoh `INTEGER`, `VARCHAR`, `TEXT`).
- HTML awalan widget untuk digunakan ketika membangun sebuah bidang formulir (sebagai contoh `<input type="text">`, `<select>`).
- Persyaratan pengesahan minimal, digunakan di admin Django dan di formulir dibangkitkan-otomatis.

Django dibekali dengan lusinan dari jenis-jenis siap pakai; anda dapat menemukan daftar lengkap dalam model field reference. Anda dapat dengan mudah menulis bidang-bidang anda sendiri jika satu siap-pakai Django tidak melakukan trik; lihat Bagaimana membuat bidang model disesuaikan.

### Pilihan bidang

Setiap bidang-bidang mengambil kumpulan tertentu dari argumen bidang-tertentu (didokumentasikan dalam model field reference). Sebagai contoh, `CharField` (dan subkelasnya) membutuhkan sebuah argumen `max_length` yang menentukan ukuran dari bidang basisdata `VARCHAR` digunakan untuk menyimpan data.

Ada juga sekumpulan dari argumen umum tersedia pada semua jenis bidang. Semua adalah pilihan. Mereka sepenuhnya dijelaskan dalam reference, tetapi ini adalah ringkasan cepat dari satu kebanyakan sering-digunakan:

`null`
  Jika `True`, Django akan menyimpan nilai-nilai kosong sebagai `NULL` di basisdata. Awalan adalah `False`.
`blank`

  Jika `True`, bidang diizinkan menjadi kosong. Awalan adalah `False`.

  Catat bahwa ini berbeda dari `null`. `blank` adalah pengesahan-terkait. Jika sebuah bidang mempunyai `blank=True`, pengesahan formulir akan mengizinkan masukan dari sebuah nilai kosong. Jika sebuah bidang mempunyai `blank=False`, bidang akan diwajibkan.

`choices`

  A sequence of 2-tuples to use as choices for this field. If this is given, the default form widget will be a select box instead of the standard text field and will limit choices to the choices given.

  Daftar pilihan kelihatan seperti ini:

      YEAR_IN_SCHOOL_CHOICES = [
          ("FR", "Freshman"),
          ("SO", "Sophomore"),
          ("JR", "Junior"),
          ("SR", "Senior"),
          ("GR", "Graduate"),
      ]

  Catatan

  A new migration is created each time the order of `choices` changes.

  Unsur pertama dalam setiap tuple adalah nilaiyang akan disimpan dalam basisdata. Unsur kedua ditampilkan oleh widget formulir bidang.

  Diberikan sebuah instance model, nilai tampilan untuk sebuah bidang dengan `choices` dapat diakses menggunakan metode `get_FOO_display()`. Sebagai contoh:

      from django.db import models

      class Person(models.Model):
          SHIRT_SIZES = [
              ("S", "Small"),
              ("M", "Medium"),
              ("L", "Large"),
          ]
          name = models.CharField(max_length=60)
          shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)

      >>> p = Person(name="Fred Flintstone", shirt_size="L")
      >>> p.save()
      >>> p.shirt_size
      'L'
      >>> p.get_shirt_size_display()
      'Large'

  You can also use enumeration classes to define `choices` in a concise way:

      from django.db import models

      class Runner(models.Model):
          MedalType = models.TextChoices("MedalType", "GOLD SILVER BRONZE")
          name = models.CharField(max_length=60)
          medal = models.CharField(blank=True, choices=MedalType.choices, max_length=10)

  Contoh-contoh lebih jauh tersedia dalam model field reference.

`default`
  Nilai awalan untuk bidang. Ini dapat berupa nilai atau obyek callable. Jika callable itu akan diapnggil setiap waktu obyek baru dibuat.
`help_text`
  Teks "help" tambahan untuk ditampilkan dengan widget formulir. Itu sangat berguna untuk dokumentasi bahkan jika bidang anda tidak digunakan pada formulir.
`primary_key`

  Jika `True`, bidang ini adalah primary key untuk model.

  Jika anda tidak menentukan `primary_key=True` untuk tiap bidang di model anda, Django akan otomatis menambahkan sebuah `IntegerField` untuk menahan primary key, jadi anda tidak butuh menyetel `primary_key=True` pada tiap bidang anda meskipun anda ingin menimpa kebiasaan primary-key awalan. Untuk lebih, lihat Bidang primary key otomatis.

  Bidang kunci utama adalah hanya-baca. Jika anda merubah nilai dari primaru key pada sebuah obyek yang ada dan kemudian menyimpan itu, sebuah obyek baru akan dibuat bersama satu yang lama. Sebagai contoh:

      from django.db import models

      class Fruit(models.Model):
          name = models.CharField(max_length=100, primary_key=True)

      >>> fruit = Fruit.objects.create(name="Apple")
      >>> fruit.name = "Pear"
      >>> fruit.save()
      >>> Fruit.objects.values_list("name", flat=True)
      <QuerySet ['Apple', 'Pear']>

`unique`
  Jika `True`, bidang ini harus unik diseluruh tabel.

Lagi, ini hanya gambaran pendek dari kebanyakan pilihan bidang umum. Rincian penuh dapat ditemukan di common model field option reference.

### Bidang primary key otomatis

By default, Django gives each model an auto-incrementing primary key with the type specified per app in `AppConfig.default_auto_field` or globally in the `DEFAULT_AUTO_FIELD` setting. For example:

    id = models.BigAutoField(primary_key=True)

If you'd like to specify a custom primary key, specify `primary_key=True` on one of your fields. If Django sees you've explicitly set `Field.primary_key`, it won't add the automatic `id` column.

Setiap model membutuhkan setidaknya satu bidang untuk memiliki `primary_key=True` (antara dinyatakan jelas atau ditambahkan otomatis).

### Nama-nama bidang bertele-tele

Setiap jenis bidang, kecuali untuk `ForeignKey`, `ManyToManyField` dan `OneToOneField`, mengambil sebuah pilihan argumen penempatan pertama -- sebuah nama bertele-tele. Jika nama bertele-tele tidak diberikan, DJango akan otomatis membuat itu menggunakan nama atribut bidang, merubah garis bawah menjadi ruang.

Dalam contoh ini, nama bertele-tele adalah `"person's first name"`:

    first_name = models.CharField("person's first name", max_length=30)

Dalam contoh ini, nama bertele-tele adalah `"first name"`:

    first_name = models.CharField(max_length=30)

`ForeignKey`, `ManyToManyField` dan `OneToOneField` membutuhkan argumen pertama untuk jadi kelas model, jadi gunakan argumen kata kunci `verbose_name`:

    poll = models.ForeignKey(
        Poll,
        on_delete=models.CASCADE,
        verbose_name="the related poll",
    )
    sites = models.ManyToManyField(Site, verbose_name="list of sites")
    place = models.OneToOneField(
        Place,
        on_delete=models.CASCADE,
        verbose_name="related place",
    )

Kebiasaan tidak menghuruf besarkan huruf pertama dari `verbose_name`. Django akan otomatis menghuruf besarkan huruf pertama dimana itu dibutuhkan.

### Hubungan

Jelas, kekuatan dari hubungan basisdata bergantung dalam tabel berkaitan ke setiap lainnya. Django menawarkan cara menentukan tiga jenis paling umum dari hubungan basisdata: many-to-one, many-to-many dan one-to-one.

#### Hubungan banyak-ke-satu

Untuk menentukan hubungan many-to-one, gunakan `ForeignKey`. Anda menggunakan itu seperti jenis `Field` lainnya: dengan menyertakan itu sebagai sebuah atribut kelas dari model anda.

`ForeignKey` membutuhkan sebuah argumen penempatan: kelas dimana model terkait.

Sebagai contoh, jika sebuah model `Car` mempunyai `Manufacturer` -- yaitu, `Manufacturer` membuat banyak mobil tetapi setiap `car` hanya mempunyai satu `Manufacturer` -- gunakan pengertian berikut:

    from django.db import models

    class Manufacturer(models.Model):
        # ...
        pass

    class Car(models.Model):
        manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
        # ...

Anda dapat juga membuat recursive relationships (sebuah obyek dengan hubungan many-to-one ke diri sendiri) dan relationships to models not yet defined; lihat the model field reference untuk rincian.

It's suggested, but not required, that the name of a `ForeignKey` field (`manufacturer` in the example above) be the name of the model, lowercase. You can call the field whatever you want. For example:

    class Car(models.Model):
        company_that_makes_it = models.ForeignKey(
            Manufacturer,
            on_delete=models.CASCADE,
        )
        # ...

Lihat juga

Bidang `ForeignKey` menerima sejumlah dari argumen tambahan yang dijelaskan dalam the model field reference. Pilihan-pilihan ini membantu menentukan bagaimana hubungan harus bekerja; semua adalah pilihan.

Untuk rincian pada mengakses obyek terkait-kebelakang, lihat Following relationships backward example.

Untuk kode contoh, lihat Many-to-one relationship model example.

#### Hubungan banyak-ke-banyak

Untuk menentukan hubungan many-to-many, gunakan `ManyToManyField`. Anda menggunakan itu seperti jenis `Field` lainnya: dengan menyertakan itu sebagai sebuah atribut kelas dari model anda.

`ManyToManyField` membutuhkan argumen penempatan: kelas pada yang model yang terkait.

Sebagai contoh, jika `Pizza` mempunyai banyak obyek `Topping`--yaitu, sebuah `Topping` dapat berupa pada banyak pizza dan setiap `Pizza` mempunyai banyak taburan -- ini adalah bagaimana anda mewakili itu:

    from django.db import models

    class Topping(models.Model):
        # ...
        pass

    class Pizza(models.Model):
        # ...
        toppings = models.ManyToManyField(Topping)

Seperti `ForeignKey`, anda dapat juga membuat recursive relationships (sebuah obyek dengan hubungan many-to-many ke itu sendiri) dan relationships to models not yet defined.

Disarankan, tetapi tidak wajib, bahwa nama dari sebuah `ManyToManyField` (`toppings` dalam contoh diatas) menjadi plural menggambarkan kumpulan dari obyek model terkait.

Itu tidak masalah model mana mempunyai `ManyToManyField`, tetapi anda harus menaruh itu dalam satu dari model - tidak keduanya.

Umumnya, instance `ManyToManyField` harus pergi ke obyek yang akan disunting pada sebuah formulir. Dalam contoh diatas, `toppings``berada dalam ``Pizza` (daripada `toppings` memiliki `Pizza` `ManyToManyField` ) karena itu lebih alami untuk berpikir tentang sebuah pizza mempunyai taburan berada pada banyak pizza. Cara itu menyetel diatas, formulir `Pizza` akan membiarkan pengguna memilih taburan.

Lihat juga

Lihat Many-to-many relationship model example untuk contoh penuh.

Bidang `ManyToManyField` juga menerima sejumlah dari argumen tambahan yang dijelaskan dalam the model field reference. Pilihan-pilihan ini membantu menentukan bagaimana hubungan harus bekerja; semua adalah pilihan.

#### Bidang tambahan pada hubungan many-to-many

When you're only dealing with many-to-many relationships such as mixing and matching pizzas and toppings, a standard `ManyToManyField` is all you need. However, sometimes you may need to associate data with the relationship between two models.

Sebagai contoh, pertimbangkan kasus dari sebuah aplikasi melacak kelompok musikal yang milik pemusik. Ada hubungan many-to-many diantara seorang dan kelompok yang mereka adalah anggota, jadi anda dapat menggunakan sebuah `ManyToManyField` untuk mewakili hubungan ini. Bagaimanapun, ada banyak dari rincian tentang keanggotaan yang mungkin ingin dikumpulkan, seperti tanggal dimana seseorang bergabung kelompok.

Untuk keadaan ini, Django mengizinkan anda menentukan model yang akan digunakan untuk menentukan hubungan many-to-many. Anda dapat kemudian menaruh bidang-bidang tambahan pada model menengah. Model menengah dikaitkan dengan `ManyToManyField` menggunakan argumen `through` untuk menunjuk model yang akan bertindak sebagai sebuah perantara. Untuk contoh pemusik kami, kode akan terlihat sesuatu seperti ini:

    from django.db import models

    class Person(models.Model):
        name = models.CharField(max_length=128)

        def __str__(self):
            return self.name

    class Group(models.Model):
        name = models.CharField(max_length=128)
        members = models.ManyToManyField(Person, through="Membership")

        def __str__(self):
            return self.name

    class Membership(models.Model):
        person = models.ForeignKey(Person, on_delete=models.CASCADE)
        group = models.ForeignKey(Group, on_delete=models.CASCADE)
        date_joined = models.DateField()
        invite_reason = models.CharField(max_length=64)

Ketika anda menyetel model perantara, anda jelas menentukan foreign key pada model-model yang terlibat dalam hubungan many-to-many. Pernyataan jelas ini menentukan bagaimana dua model terkait.

Ada beberapa batasan pada model menengah:

- Model perantara anda harus mengandung satu - dan *hanya` satu - foreign key pada model sumber (ini akan berupa `Group` dalam contoh kami), atau anda harus menentukan jelas foreign key Django harus gunakan untuk hubungan menggunakan `ManyToManyField.through_fields`. Jika anda mempunyai lebih dari satu foreign key dan `through_fields` tidak ditentukan, kesalahan pengesahan akan dimunculkan. Pembatasan yang mirip berlaku pada foreign key ke model sasaran (ini akan berupa `Person` dalam contoh kami).
- Untuk sebuah model yang mempunyai hubungan many-to-many ke itu sendiri melalui sebuah model perantara, dua foreign key pada model sama diizinkan, tetapi mereka akan diperlakukan sebagai dua sisi (berbeda) dari hubungan many-to-many. Jika ada lebih dari dua foreign key, anda harus juga menentukan `through_fields` seperti diatas, atau sebuah kesalahan pengesahan akan dimunculkan.

Now that you have set up your `ManyToManyField` to use your intermediary model (`Membership`, in this case), you're ready to start creating some many-to-many relationships. You do this by creating instances of the intermediate model:

    >>> ringo = Person.objects.create(name="Ringo Starr")
    >>> paul = Person.objects.create(name="Paul McCartney")
    >>> beatles = Group.objects.create(name="The Beatles")
    >>> m1 = Membership(
    ...     person=ringo,
    ...     group=beatles,
    ...     date_joined=date(1962, 8, 16),
    ...     invite_reason="Needed a new drummer.",
    ... )
    >>> m1.save()
    >>> beatles.members.all()
    <QuerySet [<Person: Ringo Starr>]>
    >>> ringo.group_set.all()
    <QuerySet [<Group: The Beatles>]>
    >>> m2 = Membership.objects.create(
    ...     person=paul,
    ...     group=beatles,
    ...     date_joined=date(1960, 8, 1),
    ...     invite_reason="Wanted to form a band.",
    ... )
    >>> beatles.members.all()
    <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>

You can also use `add()`, `create()`, or `set()` to create relationships, as long as you specify `through_defaults` for any required fields:

    >>> beatles.members.add(john, through_defaults={"date_joined": date(1960, 8, 1)})
    >>> beatles.members.create(
    ...     name="George Harrison", through_defaults={"date_joined": date(1960, 8, 1)}
    ... )
    >>> beatles.members.set(
    ...     [john, paul, ringo, george], through_defaults={"date_joined": date(1960, 8, 1)}
    ... )

You may prefer to create instances of the intermediate model directly.

If the custom through table defined by the intermediate model does not enforce uniqueness on the `(model1, model2)` pair, allowing multiple values, the `remove()` call will remove all intermediate model instances:

    >>> Membership.objects.create(
    ...     person=ringo,
    ...     group=beatles,
    ...     date_joined=date(1968, 9, 4),
    ...     invite_reason="You've been gone for a month and we miss you.",
    ... )
    >>> beatles.members.all()
    <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]>
    >>> # This deletes both of the intermediate model instances for Ringo Starr
    >>> beatles.members.remove(ringo)
    >>> beatles.members.all()
    <QuerySet [<Person: Paul McCartney>]>

The `clear()` method can be used to remove all many-to-many relationships for an instance:

    >>> # Beatles have broken up
    >>> beatles.members.clear()
    >>> # Note that this deletes the intermediate model instances
    >>> Membership.objects.all()
    <QuerySet []>

Once you have established the many-to-many relationships, you can issue queries. Just as with normal many-to-many relationships, you can query using the attributes of the many-to-many-related model:

    # Find all the groups with a member whose name starts with 'Paul'
    >>> Group.objects.filter(members__name__startswith="Paul")
    <QuerySet [<Group: The Beatles>]>

As you are using an intermediate model, you can also query on its attributes:

    # Find all the members of the Beatles that joined after 1 Jan 1961
    >>> Person.objects.filter(
    ...     group__name="The Beatles", membership__date_joined__gt=date(1961, 1, 1)
    ... )
    <QuerySet [<Person: Ringo Starr]>

If you need to access a membership's information you may do so by directly querying the `Membership` model:

    >>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)
    >>> ringos_membership.date_joined
    datetime.date(1962, 8, 16)
    >>> ringos_membership.invite_reason
    'Needed a new drummer.'

Another way to access the same information is by querying the many-to-many reverse relationship from a `Person` object:

    >>> ringos_membership = ringo.membership_set.get(group=beatles)
    >>> ringos_membership.date_joined
    datetime.date(1962, 8, 16)
    >>> ringos_membership.invite_reason
    'Needed a new drummer.'

#### Hubungan satu-ke-satu

Untuk menentukan hubungan one-to-one, gunakan `OneToOneField`. Anda dapat menggunakan itu hanya seperti jenis `Field` lainnya: dengan menyertakan itu sebagai sebuah atribut kelas dari model anda.

Ini adalah paling berguna pada primaty key dari sebuah obyek ketika obyek itu "extends" obyek lain di beberapa cara.

`OneToOneField` membutuhkan argumen penempatan: kelas dimana model yang terkait.

Sebagai contoh, jika anda sedang membangun sebuah basisdata dari "places", anda akan membangun hal yang cukup standar seperti alamat, nomor telepon, dll dalam basisdata. Kemudian, jika anda ingin membangun sebuah basisdata restoran di atas tempat-tempat, daripada mengulangi anda sendiri dan meniru bidang-bidang tersebut dalam model `Restaurant`, anda dapat membuat `Restaurant` memiliki kelas `OneToOneField` pada `Place` (karena sebuah restauran "adalah sebuah" tempat; faktanya, untuk menangani ini anda biasanya menggunakan inheritance, yang melibatkan sebuah hubungan jelas one-to-one).

Seperti `ForeignKey`, recursive relationship dapat ditentukan dan references to as-yet undefined models dapat dibuat.

Lihat juga

Lihat One-to-one relationship model example untuk contoh penuh.

Bidang `OneToOneField` juga menerima sebuah argumen pilihan `parent_link`.

`OneToOneField` digunakan untuk otomatis menjadi primary key pada model. Ini tidak lagi benar (meskipun anda dapat manual melewatkan dalam argumen `primary_key` jika anda suka). Dengan demikian, itu sekarang memungkinkan memiliki banyak bidang dari jenis `OneToOneField` pada model tunggal.

### Model-model lintas berkas-berkas

It's perfectly OK to relate a model to one from another app. To do this, import the related model at the top of the file where your model is defined. Then, refer to the other model class wherever needed. For example:

    from django.db import models
    from geography.models import ZipCode

    class Restaurant(models.Model):
        # ...
        zip_code = models.ForeignKey(
            ZipCode,
            on_delete=models.SET_NULL,
            blank=True,
            null=True,
        )

### Batasan bidang nama

Django menempatkan beberapa pembatasan di nama bidang model:

1. A field name cannot be a Python reserved word, because that would result in a Python syntax error. For example:

       class Example(models.Model):
           pass = models.IntegerField() # 'pass' is a reserved word!

2. Sebuah nama bidang tidak dapat mengandung lebih dari satu garis bawah dalam sebuah baris, karena cara bekerja sintaksis pencarian permintaan Django. Sebagai contoh:

       class Example(models.Model):
           foo__bar = models.IntegerField()  # 'foo__bar' has two underscores!

3. Sebuah nama bidang tidak dapat berakhir dengan sebuah garis bawah, untuk alasan yang sama.

Batasan-batasan ini dapat dipecahkan, meskipun, karena nama bidang anda tidak butuh harus cocok nama kolom basisdata anda. Lihat pilihan `db_column` .

Kata-kata pemesan SQL, seperti `join`, `where` atau `select`, adalah diizinkan sebagai nama bidang model, karena Django meloloskan semua nama-nama tabel basisdata dan nama-nama kolom di setiap permintaan SQL pokok. Itu menggunakan sintaksis mengutip dari mesin basisdata tertentu anda.

### Jenis bidang penyesuaian

Jika satu dari bidang-bidang model yang ada tidak dapat digunakan untuk memenuhi tujuan anda, atau jika anda berharap mengambil keuntungan dari beberapa jenis kolom basisdata kurang umum, anda dapat membuat kelas bidang anda sendiri. Cakupan penuh dari membuat bidang-bidang anda sendiri disediakan dalam Bagaimana membuat bidang model disesuaikan.

## Pilihan `Meta`

Memberikan model anda metadata dengan menggunakan `class Meta` sebelah dalam, seperti begitu:

    from django.db import models

    class Ox(models.Model):
        horn_length = models.IntegerField()

        class Meta:
            ordering = ["horn_length"]
            verbose_name_plural = "oxen"

Metadata model adalah "apapun yang bukan sebuah bidang", seperti pilihan pengurutan (`ordering`), nama tabel basisdata (`db_table`), atau nama-nama tunggal dan jamal dapat-dibaca-manusia (`verbose_name` dan `verbose_name_plural`). Tidak satupun diwajibkan, dan menambahkan `class Meta` pada sebuah model adalah sepenuhnya pilihan.

Daftar lengkap dar semua kemungkinan pilihan `Meta` dapat ditemukan dalam model option reference.

## Atribut model

`objects`
  Atribut paling penting dari sebuah model adalah `Manager`. Itu adalah antarmuka melalui tindakan permintaan basisdata mana yang disediakan pada model-model dan digunakan pada retrieve the instances dari basisdata. Jika tidak ada penyesuaian `Manager` ditentukan, nama awalan adalah `objects`. Pengelola hanya dapat diakses melalui kelas-kelas model, bukan instance-instance model.

## Cara model

Tentukan metode penyesuaian pada sebuah model untuk menambah fungsionalitas "tingkat-baris" pada obyek-obyek anda. Sedangkan metode `Manager` dimaksudkan melakukan hal-hal "lebar-tabel", metode model harus bertindak pada instance model tertentu.

Ini adalah teknik bernilai untuk menjaga logika bisnis dalam satu tempat -- model.

Sebagai contoh, model ini mempunyai beberapa cara penyesuaian:

    from django.db import models

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        birth_date = models.DateField()

        def baby_boomer_status(self):
            "Returns the person's baby-boomer status."
            import datetime

            if self.birth_date < datetime.date(1945, 8, 1):
                return "Pre-boomer"
            elif self.birth_date < datetime.date(1965, 1, 1):
                return "Baby boomer"
            else:
                return "Post-boomer"

        @property
        def full_name(self):
            "Returns the person's full name."
            return f"{self.first_name} {self.last_name}"

Cara terakhir di contoh ini adalah property.

model instance reference mempunyai daftar lengkap dari methods automatically given to each model. Anda dapat menimpa kebanyakan dari ini -- lihat overriding predefined model methods, dibawah -- tetapi ada sepasang yang anda akan hampir selalu ingin tentukan:

`__str__()`

  "magic methode" Python yang mengembalikan sebuah string mewakili obyek apapun. Ini adalah apa Python dan Django akan gunakan ketika sebuah instance model butuh dipaksa dan ditampilkan sebagai sebuah string kosong. Kebanyakan terutama, ini terjadi ketika anda menampilkan sebuah obyek dalam sebuah konsol interaktif atau dalam admin.

  Anda akan selalu ingin menentukan cara ini; cara awal tidak membantu sama sekali.

`get_absolute_url()`

  Ini memberitahu Django bagaimana menghitung URL untuk sebuah obyek. Django menggunakan ini dalam antarmuka adminnya, dan kapan pun itu butuh mencari tahu untuk sebuah obyek.

  Obyek apapun yang mempunyai sebuah URL yang unik mencirikan itu harus menentukan metode ini.

### Menimpa metode model yang detetapkan

Ada kumpulan lain dari model methods yang mengenkapsulasi sekolompok perilaku basisdata yang anda akan ingin sesuaikan. Khususnya anda akan sering ingin dirubah merubah cara `save()` dan `delete()` bekerja.

Anda bebas untuk menimpa metode ini (dan cara model lainnya) untuk merubah perilaku.

Sebuah penggunaan-kasus klasik untuk menimpa metode-metode siap pakai jika anda ingin sesuatu terjadi ketika anda menyimpan sebuah obyek. Sebagai contoh (lihat `save()` untuk dokumentasi dari parameter-parameter itu terima):

    from django.db import models

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()

        def save(self, *args, **kwargs):
            do_something()
            super().save(*args, **kwargs)  # Call the "real" save() method.
            do_something_else()

Anda dapat juga mencegah mengatakan:

    from django.db import models

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()

        def save(self, *args, **kwargs):
            if self.name == "Yoko Ono's blog":
                return  # Yoko shall never have her own blog!
            else:
                super().save(*args, **kwargs)  # Call the "real" save() method.

Itu adalah penting diingat untuk memanggil metode super kelas -- yaitu bahwa bisnis `super().save(*args, **kwargs)` -- memastikan bahwa obyek masih mendapatkan tersimpan kedalam basisdata. Jika anda lupa memanggil metode superkelas, perilaku awalan tidak akan terjadi dan basisdata tidak akan disentuh.

Itu juga penting bahwa anda melewati argumen yang dapat diloloskan ke metode model -- yaitu apa `*args, **kwargs` sedikit lakukan, Django akan, dari waktu ke waktu, memperpanjang kemampuan metode model siap-pakai, menambahkan argumen-argumen baru. Jika anda menggunakan `*args, **kwargs` dalam pengertian metode anda, anda dijamin bahwa kode anda akan otomatis mendukung argumen-argumen tersebut ketika mereka ditambahkan.

If you wish to update a field value in the `save()` method, you may also want to have this field added to the `update_fields` keyword argument. This will ensure the field is saved when `update_fields` is specified. For example:

    from django.db import models
    from django.utils.text import slugify

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        slug = models.TextField()

        def save(
            self, force_insert=False, force_update=False, using=None, update_fields=None
        ):
            self.slug = slugify(self.name)
            if update_fields is not None and "name" in update_fields:
                update_fields = {"slug"}.union(update_fields)
            super().save(
                force_insert=force_insert,
                force_update=force_update,
                using=using,
                update_fields=update_fields,
            )

See Menentukan bidang-bidang mana yang disimpan for more details.

Menimpa metode-metode model tidak dipanggil pada tindakan massal

Catat bahwa metode `delete()` untuk sebuah obyej tidak dibutuhkan dipanggil ketika deleting objects in bulk using a QuerySet atau sebagai sebuah hasil dari sebuah `cascading delete`. Untuk memastikan penyesuaian logika hapus dijalankan, anda dapat menggunakan sinyal `pre_delete` dan/atau `post_delete`.

Sayangnya tidak ada pemecahan ketika obyek `creating` atau `updating` dalam jumlah besar, sejak tidak satupun dari `save()`, `pre_save`, dan `post_save` dipanggil.

### Menjalankan penyesuaian SQL

Pola umum lain sdang menulis pernyataan SQL penyesuaian dalam metode-metode model dan metode-metode tingkat-modul. Untuk rincian lebih pada menggunakan SQL mentah, lihat dokumentasi pada using raw SQL.

## Model warisan

Warisan model dalam Django bekerja hampir sama pada cara biasa warisan kelas bekerja dalam Python, tetapi dasar-dasar pada permulaan dari halaman harus masih diikuti. Itu berarti kelas dasar harus mensubkelaskan `django.db.models.Model`.

Satu-satunya keputusan yang anda punya untuk membuat apakah anda ingin model-model induk menjadi model-model dalam hak mereka sendiri (dengan tabel-tabel basisdata mereka sendiri), atau jika induk hanya menampung dari informasi umum yang akan hanya nampak melalui model-model anak.

Ada tiga gaya warisan yang mungkin di Django.

1. Sering, anda akan hanya ingin menggunakan kelas induk untuk menampung informasi yang anda tidak ingin miliki untuk mengetikkan setiap model anak. Kelas ini tidak akan pernah digunakan dalam pengasingan, jadi Kelas-kelas dasar abstrak adalah apa yang anda kejar.
2. Jika anda sedang mensubkelaskan sebuah model yang ada (mungkin sesuatu dari aplikasi lain seluruhnya) dan ingin setiap model memiliki tabel basisdata itu sendiri, Warisan banyak-tabel adalah cara untuk pergi.
3. Akhirnya, jika anda hanya ingin merubah perilaku tingkat-Python dari sebuah model, tanpa merubah bidang-bidang model dalam cara apapun, anda dapat menggunakan Model proxy.

### Kelas-kelas dasar abstrak

Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put `abstract=True` in the Meta class. This model will then not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class.

Sebuah contoh:

    from django.db import models

    class CommonInfo(models.Model):
        name = models.CharField(max_length=100)
        age = models.PositiveIntegerField()

        class Meta:
            abstract = True

    class Student(CommonInfo):
        home_group = models.CharField(max_length=5)

Model `Student` akan mempunyai tiga bidang: `name`, `age` dan `home_group`. Model `CommonInfo` tidak dapat digunakan sebagai model Django biasa, sejak itu adalah sebuah kelas dasar abstrak. Itu tidak membangkitkan sebuah tabel basisdata atau mempunyai sebuah pengelola, dan tidak dapat di instansiasikan atau disimpan langsung.

Fields inherited from abstract base classes can be overridden with another field or value, or be removed with `None`.

Untuk banyak penggunaan, jenis ini dari warisan model akan tepatnya apa yang anda inginkan. Itu menyediakan sebuah cara untuk faktor luar informasi umum pada tingkat Python, selagi masih hanya membuat satu tabel basisdata per model anak pada tingkat basisdata.

#### `Meta` warisan

Ketika sebuah kelas dasar abstrak dibuat, Django membuat kelas sebelah dalam Meta apapun anda nyatakan di kelas dasar tersedia sebagai sebuah atribut. Jika sebuah kelas anak tidak menyatakan kelas Meta nya sendiri, itu akan mewarisi Meta induk. Jika anak ingin memperpanjang kelas Meta induk, itu dapat mensubkelaskan itu. Sebagai contoh:

    from django.db import models

    class CommonInfo(models.Model):
        # ...
        class Meta:
            abstract = True
            ordering = ["name"]

    class Student(CommonInfo):
        # ...
        class Meta(CommonInfo.Meta):
            db_table = "student_info"

Django does make one adjustment to the Meta class of an abstract base class: before installing the Meta attribute, it sets `abstract=False`. This means that children of abstract base classes don't automatically become abstract classes themselves. To make an abstract base class that inherits from another abstract base class, you need to explicitly set `abstract=True` on the child.

Beberapa atribut tidak akan masuk akal untuk disertakan dalam kelas Meta dari sebuah kelas dasar abstrak. Sebagai coontoh, menyertakan `db_table` akan berarti bahwa semua kelas-kelas anak (satu yang tidak menentukan milik mereka Meta) akan menggunakan tabel basisdata sama, yang hampir pasti bukan yang anda inginkan.

Due to the way Python inheritance works, if a child class inherits from multiple abstract base classes, only the Meta options from the first listed class will be inherited by default. To inherit Meta options from multiple abstract base classes, you must explicitly declare the Meta inheritance. For example:

    from django.db import models

    class CommonInfo(models.Model):
        name = models.CharField(max_length=100)
        age = models.PositiveIntegerField()

        class Meta:
            abstract = True
            ordering = ["name"]

    class Unmanaged(models.Model):
        class Meta:
            abstract = True
            managed = False

    class Student(CommonInfo, Unmanaged):
        home_group = models.CharField(max_length=5)

        class Meta(CommonInfo.Meta, Unmanaged.Meta):
            pass

#### Hati-hati dengan `related_name` dan `related_query_name`

Jika anda sedang menggunakan `related_name` atau `related_query_name` pada `ForeignKey` atau `ManyToManyField`, anda harus selalu menentukan unik membalikkan nama dan permintaan nama untuk bidang. Ini akan biasanya menyebabkan sebuah masalah dalam kelas-kelas berdasarkan abstrak, sejak bidang-bidang pada kelas ini disertakan kedalam setiap kelas-kelas anak, yang tepatnya nilai-nilai sama untuk atribut-atribut (termasuk `related_name` dan `related_query_name`) setiap kali.

Untuk pemecahan masalah ini, ketika anda sedang menggunakan `related_name` atau `related_query_name` dalam sebuah kelas dasar abstrak (hanya) bagian dari nilai harus mengandung `'%(app_label)s'` dan `'%(class)s'`.

- `'%(class)s'` is replaced by the lowercased name of the child class that the field is used in.
- `'%(app_label)s'` is replaced by the lowercased name of the app the child class is contained within. Each installed application name must be unique and the model class names within each app must also be unique, therefore the resulting name will end up being different.

Sebagai contoh, diberikan sebuah aplikasi `common/models.py`:

    from django.db import models

    class Base(models.Model):
        m2m = models.ManyToManyField(
            OtherModel,
            related_name="%(app_label)s_%(class)s_related",
            related_query_name="%(app_label)s_%(class)ss",
        )

        class Meta:
            abstract = True

    class ChildA(Base):
        pass

    class ChildB(Base):
        pass

Bersama dengan aplikasi lainnya `rare/models.py`:

    from common.models import Base

    class ChildB(Base):
        pass

Membalikkan nama dari bidang `common.ChildA.m2m` akan menjadi `common_childa_related` dan membalikkan permintaan nama akan menjadi `common_childas`. Membalikkan nama dari bidang `common.ChildB.m2m` akan menjadi `common_childb_related` dan membalikkan permintaan nama akan menjadi `common_childbs`. Akhirnya, membalikkan nama dari bidang `rare.ChildB.m2m` akan menjadi `rare_childb_related` dan membalikkan permintaan nama akan menjadi `rare_childbs`. Itu terserah anda bagaimana anda menggunakan bagian `'%(class)s'` dan `'%(app_label)s'` untuk membangun nama terhubung anda atau permintaan nama terhubung tetapi jika anda lupa menggunakan itu, Django akan memunculkan kesalahan-kesalahan ketika anda melalukan pemeriksaan sistem (atau menjalankan `migrate`).

Jika anda tidak menentukan sebuah atribut `related_name` untuk sebuah bidang dalam kelas dasar abstrak, membalikkan nama awalan akan menjadi nama dari kelas anak diikuti oleh `'_set'`, seperti itu biasanya akan menjadi jika anda telah menyatakan bidang langsung pada kelas anak. Sebagai contoh, dalam kode diatas, jika atribut `related_name` dihilangkan, membalikkan nama untuk bidang `m2m` kan menjadi `childa_set` dalam kasus `ChildA` dan `childb_set` untuk bidang `ChildB`.

### Warisan banyak-tabel

Jenis kedua dari warisan model didukung oleh Django adalah ketika setiap model dalam hirarki adalah sebuah model semua oleh itu sendiri. Setiap model berhubungan ke tabel basisdata itu sendiri dan dapat diminta dan dibuat sendiri-sendiri. Hubungan warisan memperkenalkan tautan diantara model anak dan setiap dari induknya (melalui dibuat-otomatis `OneToOneField`). Sebagai contoh:

    from django.db import models

    class Place(models.Model):
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=80)

    class Restaurant(Place):
        serves_hot_dogs = models.BooleanField(default=False)
        serves_pizza = models.BooleanField(default=False)

All of the fields of `Place` will also be available in `Restaurant`, although the data will reside in a different database table. So these are both possible:

    >>> Place.objects.filter(name="Bob's Cafe")
    >>> Restaurant.objects.filter(name="Bob's Cafe")

If you have a `Place` that is also a `Restaurant`, you can get from the `Place` object to the `Restaurant` object by using the lowercase version of the model name:

    >>> p = Place.objects.get(id=12)
    # If p is a Restaurant object, this will give the child class:
    >>> p.restaurant
    <Restaurant: ...>

Bagaimanapun, jika `p` dalam contoh-contoh diatas bukan sebuah `Restaurant` (itu telah dibuat langsung sebagai sebuah obyek `Place` atau induk dari beberapa kelas lain(, mengacu pada `p.restaurant` akan memunculkan sebuah pengecualian `Restaurant.DoesNotExist`.

`OneToOneField` dibuat-otomatis pada `Restaurant` yang mengkaitkan itu ke `Place` terlihat seperti ini:

    place_ptr = models.OneToOneField(
        Place,
        on_delete=models.CASCADE,
        parent_link=True,
        primary_key=True,
    )

Anda dapat menimpa bidang itu dengan menyatakan `OneToOneField` anda sendiri dengan `parent_link=True` pada `Restaurant`.

#### `Meta` dan warisan banyak-tabel

Dalam keadaan warisan banyak-tabel, itu tidak masuk akal untuk sebuah kelas anak mewarisi dari kelas Meta induknya. Semua pilihan Meta telah diberlakukan ke kelas induk dan memberlakukan mereka kembali akan biasanya hanya membawa ke perilaku bertentangan (ini adalah berlawanan dengan kasus kelas dasar abstrak, dimana kelas dasar tidak ada dalam hak itu sendiri).

Jadi sebuah model anak tidak mempunyai akses ke kelas Meta induknya. Bagaimanapun, ada sedikit kasus terbatas ketika anak mewarisi perilaku dari induk: jika anak tidak menentukan sebuah atribut `ordering` atau sebuah atribut `get_latest_by`, itu akan mewarisi ini dari induknya.

Jika induk mempunyai sebuah pengurutan dan anda tidak ingin anak mempunyai pengurutan alami, anda dapat jelas meniadakan itu:

    class ChildModel(ParentModel):
        # ...
        class Meta:
            # Remove parent's ordering effect
            ordering = []

#### Mewarisi dan membalikkan hubungan

Karena warisan banyak-tabel menggunakan sebuah `OneToOneField` ersirat pada tautan anak dan induk, itu memungkinkan memindahkan dari induk turun ke anak, seperti dalam contoh diatas. Bagaimanapun, ini menggunakan nama yang nilai `related_name` awalannya untuk hubungan `ForeignKey` dan `ManyToManyField`. Jika anda sedang menaruh jenis itu dari hubungan pada sebuah subkelas dari model induk, anda harus menentukan atribut `related_name` pada setiap bidang itu. Jika anda lupa, Django akan memunculkan sebuah kesalahan pengesahan.

Sebagai contoh, menggunakan kelas `Place` diatas lagi, mari kita membuat subkelas lain dengan sebuah `ManyToManyField`:

    class Supplier(Place):
        customers = models.ManyToManyField(Place)

This results in the error:

    Reverse query name for 'Supplier.customers' clashes with reverse query
    name for 'Supplier.place_ptr'.

    HINT: Add or change a related_name argument to the definition for
    'Supplier.customers' or 'Supplier.place_ptr'.

Menambahkan `related_name` ke bidang `customers` seperti berikut akan menyelesaikan kesalahan: `models.ManyToManyField(Place, related_name='provider')`.

#### Menentukan bidang tautan induk

Sebagai disebutkan, Django akan otomatis membuat sebuah `OneToOneField` menghubungkan ke kelas anak anda kembali ke model induk bukan-abtrak apapun. Jika anda ingin mengendalikan nama dari atribut menghubungkan kembali ke induk, anda dapat membuat `OneToOneField` anda sendiri dan menyetel `parent_link=True` untuk menunjukkan bahwa bidang anda menghubungkan kembali ke kelas induk.

### Model proxy

Ketika menggunakan multi-table inheritance, tabel basisdata baru dibuat untuk setiap subkelas dari model. Ini biasanya keinginan kebiasaan, sejak subkelas butuh tempar menyimpan bidang data tambahan apapun yang tidak hadir pada kelas dasar. Terkadang, bagaimanapun, anda hanya ingin merubah kebiasaan Python dari model -- mungkin merubah pengelola awalan, atau menambah metode baru.

Ini adalah kegunaan warisan model proxy: membuat sebuah proxy untuk model asli. Anda dapat membuat, menghapus dan memperbaharui instance-instance dari model proxy dan semua data akan disimpan seperti jika anda sedang menggunakan model (bukan-proxy) asli. Perbedaannya adalah bahwa anda dapat merubah hal-hal seperti pengurutan model awalan atau pengelola awalan dalam proxy, tanpa harus merubah aslinya.

Model proxy dinyatakan seperti model-model biasa. Anda memberitahu Django bahwa model proxynya dengan mengatur atribut `proxy` dari kelas `Meta` menjadi `False`.

Sebagai contoh, misalnya anda ingin menambahkan sebuah metode ke model `Person`. Anda dapat melakukannya seperti ini:

    from django.db import models

    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)

    class MyPerson(Person):
        class Meta:
            proxy = True

        def do_something(self):
            # ...
            pass

The `MyPerson` class operates on the same database table as its parent `Person` class. In particular, any new instances of `Person` will also be accessible through `MyPerson`, and vice-versa:

    >>> p = Person.objects.create(first_name="foobar")
    >>> MyPerson.objects.get(first_name="foobar")
    <MyPerson: foobar>

You could also use a proxy model to define a different default ordering on a model. You might not always want to order the `Person` model, but regularly order by the `last_name` attribute when you use the proxy:

    class OrderedPerson(Person):
        class Meta:
            ordering = ["last_name"]
            proxy = True

Sekarang permintaan `Person` biasa akan tidak diurutkan dan permintaan `OrderedPerson` akan diurutkan berdasarkan `last_name`.

Model-model proxy mewarisi atribut `Meta` in the same way as regular models.

#### `QuerySet` masih mengembalikan model yang telah diminta

Tidak ada jalan Django kembali, katakan, sebuah obyek `MyPerson` kapanpun anda meminta untuk obyek `Person`. Sebuah queryset untuk obyek `Person` akan mengembalikan jenis-jenis itu dari obyek. Titik keseluruhan dari obyek proxy adalah bahwa kode bergantung pada `Person` asli akan menggunakan itu dan kode anda sendiri dapat menggunakan perpanjangan anda sertakan (yang tidak ada kode lain bergantung bagaimanapun) Itu bukan sebuah cara mengganti `Person` (atau model lain) dimanapun dengan sesuatu dari pembuatan anda sendiri.

#### Batasan kelas dasar

Sebuah model proxy harus mewarisi dari tepatnya satu kelas model bukan-abstrak. Anda tidak dapat mewarisi dari banyak model bukan-abstrak sebagai model proxy tidak menyediakan hubungan apapun diantara baris-baris dalam tabel-tabel basisdata berbeda. Sebuah model proxy dapat mewarisi dari angka apapun dari kelas-kelas model abstrak, menyediakan mereka tidak menentukan bidang-bidang model apapun. Sebuah model proxy mungkin juga mewarisi dari angka apapun dari model-model proxy yang berbagi kelas induk bukan-abstrak umum.

#### Pengelola model proxy

Jika anda tidak menentukan pengelola model apapun pada model proxy, itu mewarisi pengelola dari induk modelnya. Jika anda menentukan sebuah pengelola pada model proxy, itu akan menjadi awalan, meskipun pengelola apapun ditentukan pada kelas-kelas induk akan masih tersedia.

Melanjutkan contoh kami dari atas, anda dapat merubah pengelola awalan digunakan ketika anda meminta model `Person` seperti ini:

    from django.db import models

    class NewManager(models.Manager):
        # ...
        pass

    class MyPerson(Person):
        objects = NewManager()

        class Meta:
            proxy = True

Jika anda ingin menambahkan sebuah pengelola baru pada Proxy, tanpa mengganti awalan yang ada, anda dapat menggunakan teknik-teknik digambarkan dalam dokumentasi custom manager : buat sebuah kelas dasar mengandung pengelola baru dan mewarisi itu setelah kelas dasar utama:

    # Create an abstract class for the new manager.
    class ExtraManagers(models.Model):
        secondary = NewManager()

        class Meta:
            abstract = True

    class MyPerson(Person, ExtraManagers):
        class Meta:
            proxy = True

Anda mungkin tidak butuh melakukan ini terlalu sering, tetapi, ketika anda melakukan, sangat memungkinkan.

#### Perbedaan diantara warisan proxy dan model tidak dikendalikan

Warisan model proxy mungkin terlihat cukup mirip untuk membuat sebuah model tidak dikendalikan, menggunakan atribut `managed` pada kelas `Meta` model.

Dengan pengaturan hati-hati dari `Meta.db_table` anda dapat membuat sebuah model tidak dikendalikan yang membayangi sebuah model yang ada dan menambahkan metode-metode Python pada itu. Bagaimanapun, bahwa akan menjadi berulang dan rentan ketika anda butuh menjaga kedua salinan sinkronisasi jika anda membuat perubahan apapun.

Di sisi lain, model-model proxy berusaha untuk berperilaku tepatnya seperti model mereka sedang memproxikan. Mereka selalu dalam sinkronisasi dengan model induk sejak mereka langsung mewarisi bidang-bidang dan pengelolanya.

Aturan-aturan umum adalah:

1. Jika anda sedang mencerminkan model yang ada atau tabel basisdata dan tidak ingin semua kotom tabel basisdata asli, gunakan `Meta.managed=False`. Pilihan itu biasanya berguna untuk permodelan tampilan basisdata dan tabel tidak dibawah kendali Django.
2. Jika anda ingin merubah perilaku hanya-Python dari sebuah model, tetapi menjaga semua bidang sama sebagai dalam aslinya, gunakan `Meta.proxy=True`. Ini menyetel sehingga model proxy adalah sebuah salinan tepat dari struktur penyimpanan dari model asli ketika data disimpan.

### Banyak warisan

Sama seperi pensubkelasan Python, itu memungkinkan untuk model Django untuk mewarisi dari banyak model induk. Mengingat bahwa aturan keputusan nama Python biasa berlaku. Kelas dasar pertama yang nama tertentu (sebagai contoh Meta 1) muncul akan menjadi satu yang digunakan; sebagai contoh, ini berarti bahwa jika banyak induk mengandung kelas Meta 2, hanya satu pertama yang akan digunakan, dan semua lainnya akan diabaikan.

Umumnya, anda tidak akan butuh mewarisi banyak induk. Kasus-kegunaan utama dimana ini berguna adalah untuk kelas "mix-in": menambahkan bidang ekstra tertentu atau metode pada setiap kelas yang mewarisi mix-in. Coba untuk menjaga hirarki warisan anda sesederhana dan semudah mungkin sehingga anda tidak harus berjuang bekerja diluar dimana potongan tertentu dari informasi berasal.

Catat bahwa mewarisi dari banyak model yang mempunyai primary key `id` umum akan memunculkan sebuah kesalahan. Untuk penggunaan benar warisan banyak, anda dapat menggunakan `AutoField` jelas dalam model dasar.

    class Article(models.Model):
        article_id = models.AutoField(primary_key=True)
        ...

    class Book(models.Model):
        book_id = models.AutoField(primary_key=True)
        ...

    class BookReview(Book, Article):
        pass

Atau gunakan leluhur paling umum untuk menahan `AutoField`. Ini mewajibkan menggunakan sebuah `OneToOneField` secara jelas dari setiap model induk pada leluhur umum untuk menghindari bentrokan diantara bidang yang otomatis dibangkitkan dan diwarisi oleh anak:

    class Piece(models.Model):
        pass

    class Article(Piece):
        article_piece = models.OneToOneField(
            Piece, on_delete=models.CASCADE, parent_link=True
        )
        ...

    class Book(Piece):
        book_piece = models.OneToOneField(Piece, on_delete=models.CASCADE, parent_link=True)
        ...

    class BookReview(Book, Article):
        pass

### Nama bidang "hiding" tidak diizinkan

Dalam warisan kelas Python biasan itu diizinkan untuk kelas anak menimpa atribut apapun dari kelas induk. Dalam Django, ini tidak biasanya diizinkan untuk bidang model. Jika kelas dasar model bukan-abstrak mempunyai sebuah bidang disebut `author`, anda tidak dapat membuat bidang model lain atau menentukan sebuah atribut disebut `author` dalam kelas apapun yang mewarisi dari kelas dasar.

Batasan ini tidak berlaku ke bidang model diwarisi dari sebuah model abstrak. Bidang itu mungkin ditimpa dengan bidang atau nilai lain, atau dipindahkan dengan mengatur `field_name = None`.

Peringatan

Pengelola model diwarisi dari kelas-kelas dasar abstrak. menimpa sebuah bidang warisan yang diacukan oleh sebuah `Manager` warisan mungkin menyebabkan kesalahan halus. Lihat custom managers and model inheritance 1.

Catatan

Beberapa bidang-bidang menentukan tambahan atribut pada model, sebagai contoh sebuah `ForeignKey` menentukan sebuah tambahan atribut dengan `_id` ditambahkan pada nama bidang, sama halnya `related_name` dan `related_query_name` pada model asing.

Atribut-atribut tambahan ini tidak dapat ditambahkan meskipun bidang yang menentukan itu berubah atau dipindahkan sehingga itu tidak lagi menentukan atribut tambahan.

Menimpa bidang-bidang dalam model induk membawa ke kesulitan dalam kawasan seperti pengawalan instance baru (menentukan bidang mana sedang diawalkan dalam `Model.__init__`) dan serialisasi. Ini adalah fitur-fitur yang warisan kelas Python biasa tidak harus berurusan dengan cara yang sama, jadi perbedaan diantara kelas warisan model Django tidak berubah-ubah.

Pembatasan ini hanya berlaku pada atribut-atribut yang adalah instance `Field`. Atribut Python biasa dapat ditimpa jika anda harapkan. Itu juga hanya berlaku pada nama dari atribut seperti Python lihat: jika anda sedang secara manual menentukan nama kolom basisdata, anda dapat mempunyai nama kolom sama muncul di kedua model anak dan leluhur untuk warisan banyak-tabel (mereka adalah kolom-kolom dalam dua tabel-tabel basisdata berbeda).

Django akan memunculkan sebuah `FieldError` jika anda menimpa bidang model apapun dalam model pendahulu apapun.

Note that because of the way fields are resolved during class definition, model fields inherited from multiple abstract parent models are resolved in a strict depth-first order. This contrasts with standard Python MRO, which is resolved breadth-first in cases of diamond shaped inheritance. This difference only affects complex model hierarchies, which (as per the advice above) you should try to avoid.

## Mengorganisasikan model-model dalam sebuah paket

Perintah `manage.py startapp` membuat sebuah struktur aplikasi yang menyertakan sebuah berkas `models.py`. Jika anda mempunyai banyak model, mengorganisasikan mereka dalam berkas-berkas terpisah mungkin membantu.

Untuk melakukannya, buat sebuah paket `models`. Pindahkan `models.py` dan buat sebuah direktori `myapp/models/` dengan sebuah berkas `__init__.py` dan berkas-berkas untuk menyimpan model-model anda. Anda harus mengimpor model-model dalam berkas `__init__.py`.

Sebagai contoh, jika anda mempunyai `organic.py` dan `synthetic.py` dalam direktori `models`:

`myapp/models/__init__.py`

    from .organic import Person
    from .synthetic import Robot

Jelas mengimpor setiap model daripada menggunakan `from .models import *` mempunyai keuntungan dari tidak berantakan namespace, membuat kode lebih dapat dibaca, dan menjaga alat analisa kode berguna.

Lihat juga

Acuan Model
  Meliputi semua API terkait model termasuk bidang-bidang model, obyek terkait, dan `QuerySet`.