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" serial NOT NULL PRIMARY KEY,
    "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 Menulis bidang model penyesuaian.

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

Sebuah perulangan (yaitu, sebuah daftar atau tuple) dari 2-tuple digunakan sebagai pilihan untuk bidang ini. Jika ini diberikan, widget formulir awalan akan berupa kotak pilih daripada bidang teks standar dan akan membatasi pilihan pada pilihan diberikan.

Daftar pilihan kelihatan seperti ini:

YEAR_IN_SCHOOL_CHOICES = (
    ('FR', 'Freshman'),
    ('SO', 'Sophomore'),
    ('JR', 'Junior'),
    ('SR', 'Senior'),
    ('GR', 'Graduate'),
)

Unsur pertama dalam setiap tuple adalah nilai yang akan disimpan dalam basisdata. Unsur kedua akan diperlihatkan oleh widget formulir awalan atau dalam sebuah ModelChoiceField. Memberikan sebuah instance model, nilai diperlihatkan untuk bidang pilihan 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'
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

Secara awal, Django memberikan setiap model bidang berikut:

id = models.AutoField(primary_key=True)

Ini adalah primary key peningkatan-otomatis.

Jika anda suka menentukan primary key penyesuaian, cukup tentukan primary_key=True pada satu dari bidang-bdiang anda. Jika Django melihat anda telah jelas menyetel Field.primary_key, itu tidak akan menambahkan kolom id otomatis.

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.

Disarankan, tetapi tidak wajib, bahwa nama dari bidang ForeignKey (manufacturer dalam contoh diatas) menjadi nama dari model, huruf kecil. Anda dapat, tentu saja, memanggil bidang apapun kamu ingin. Sebagai contoh:

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

Jika anda hanya berurusan dengan hubungan many-to-many sederhana seperti mixin dan mencocokkan pizza dan taburan, sebuah ManyToManyField standar adalah semua yang anda butuhkan. Bagaimanapun, terkadang anda mungkin butuh mengkaitkan data dengan hubungan diantara dua model.

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):              # __unicode__ on Python 2
        return self.name

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

    def __str__(self):              # __unicode__ on Python 2
        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.
  • Ketika menentukan hubungan many-to-many dari model kepada itu sendiri, menggunakan model perantara, anda harus menggunakan symmetrical=False (lihat the model field reference).

Sekarang yang anda telah menyetel ManyToManyField anda untuk menggunakan model pertengangan kami (Membership, dalam kasus ini), anda siap mulai membuat beberapa hubungan many-to-many. Anda melakukan ini dengan membuat instance-instance dari model pertengahan:

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

Tidak seperti bidang many-to-many biasa, anda tidak dapat menggunakan add(), create(), atau set() untuk membuat hubungan:

>>> # The following statements will not work
>>> beatles.members.add(john)
>>> beatles.members.create(name="George Harrison")
>>> beatles.members.set([john, paul, ringo, george])

MEngapa? anda tidak dapat membuat sebuah hubungan diantara Person dan Group - anda butuh menentukan semua rincian untuk hubungan diwajibkan oleh model Membership. Panggilan add, create dan penugasan tidak menyediakan sebuah cara untuk menentukan rincian tambahan ini. Sebagai sebuah hasil, mereka ditiadakan untuk hubungan many-to-many yang menggunakan sebuah model pertengahan. Cara satu-satunya untuk membuat jenis ini dari hubungan adalah membuat instance-instance dari model pertengahan.

Metode remove() ditiadakan untuk alasan mirip. Sebagai contoh, jika penyesuaian melalui tabel ditentukan oleh model pertengahan tidak melaksanakan keunikan pada pasangan (model1, model2), panggilan remove() tidak akan cukup menyediakan informasi untuk yang instance model pertengahan harus dihapus:

>>> 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 will not work because it cannot tell which membership to remove
>>> beatles.members.remove(ringo)

Bagaimanapun, metode clear() dapat digunakan untuk memindahkan semua hubungan many-to-many untuk sebuah contoh:

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

Sekali anda telah membangun hubungan many-to-many dengan membuat instance-instance dari model pertengahan anda, anda dapat menerbitkan permintaan-permintaan. Seperti dengan hubungan biasa many-to-many, anda dapat meminta menggunakan atribut-atribut dari model hubungan-many-to-many:

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

Ketika anda sedang menggunakan model menengah, anda dapat juga meminta pada atributnya:

# 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]>

Jika anda butuh mengakses informasi keanggotaan anda mungkin melakukan itu dengan langsung meminta model Membership:

>>> 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.'

cara lain mengakses informasi sama adalah dengan meminta many-to-many reverse relationship dari obyek Person:

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

Ini sangat OKE untuk menghubungkan model ke satu dari aplikasi lain. Untuk melakukan ini, impor model terkait pada atas dari berkas dimana model anda ditentukan. Kemudian, cukup mengacu ke kelas model lain dimana dibutuhkan. Sebagai contoh:

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 hanya dua batasan pada model nama bidang:

  1. Sebuah nama bidang tidak dapat berupa sebuah kata cadangan Python, karena itu akan menghasilkan dalam kesalahan sintaksis. Sebagai contoh:

    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!
    

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 Menulis bidang model penyesuaian.

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 '%s %s' % (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__() (Python 3)

"metode ajaib" Python yang mengembalikan sebuah unicode "perwakilan" dari obyek. Ini adalah apa Python dan Django akan gunakan kapanpun sebuah instance model butuh dipaksa dan ditambilkan sebagai string polos. Terutama, ini terjadi ketika anda memperlihatkan sebuah obyek dalam sebuah konsol interaktif atau dalam admin.

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

__unicode__() (Python 2)
Python 2 equivalent of __str__().
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(Blog, self).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(Blog, self).save(*args, **kwargs) # Call the "real" save() method.

Itu adalah penting mengingat untuk memanggil metode super kelas -- yaitu bahwa bisnis super(Blog, self).save(*args, **kwargs) -- untuk memastikan bahwa obyek masih disimpan kedalam basisdata. jika anda lupa untuk memanggil metode super kelas, perilaku awalan tidak akan terjadi dan basisdata tidak 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.

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

Kelas-kelas dasar abstrak berguna ketika anda ingin menaruh beberapa informasi umum kedalam sejumlah model-model lain. Anda menulis kelas dasar anda dan menaruh abstract=True dalam kelas Meta. Model ini kemudian tidak digunakan untuk membuat tabel basisdata apapun. Malahan, ketika itu digunakan sebagai kelas dasar untuk model-model lain, bidangnya akan ditambahkan ke kelas anak mereka. Itu adalah sebuah kesalahan memiliki bidang-bidang dalam kelas dasar abstrak dengan nama sama sepertimereka dalam anak (dan Django akan memunculkan sebuah pengecualian).

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.

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 membuat satu penyesuaian pada kelas Meta dari kelas dasar abstrak: sebelum memasang atribut Meta, itu menyetel abstract=False. Ini berarti bahwa anak dari kelas-kelas dasar abstrak tidak otomatis menjadi kelas-kelas abstrak mereka sendiri. Tentu saja, anda dapat membuat sebuah kelas dasar abstrak yang mewarisi dari kelas dasar abstrak lain. Anda hanya butuh mengingat untuk menjelaskan menyetel abstract=True setiap kali.

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.

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)

Semua dari bidang-bidang dari Place akan juga tersedia dalam Restaurant, meskipun data akan tinggal dalam tabel basisdata berbeda. Jadi kedua ini memungkinkan:

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

Jika anda mempunyai sebuah Place yang juga sebuah Restaurant, anda dapat ambil dari obyek Place ke obyek Restaurant dengan menggunakan versi huruf-kecil dari nama model:

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

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)

Ini hasil di kesalahan:

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').

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

Kelas MyPerson berjalan pada tabel basisdata sama seperti induknya kelas Person. Khususnya, instance baru apapun dari Person akan juga diakses melalui MyPerson, dan sebaliknya:

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

Anda dapat juga menggunakan sebuah model proxy untuk menentukan pengurutan awalan berbeda pada sebuah model. Anda mungkin tidak inging mengurutkan model Person, tetapi umumnya pengurutan oleh atribut last_name ketika anda menggunakan proxy. Ini adalah mudah:

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.

Changed in Django 1.10:

Dalam versi paling awal, sebuah model proxy tidak dapat mewarisi lebih dari satu model proxy yang berbagi kelas induk sama.

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.

Changed in Django 1.10:

Kemampuan menimpa bidang-bidang abstrak telah ditambahkan.

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.

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.
Back to Top