Diberikan model Django, saya mencoba mendaftar semua bidangnya. Saya telah melihat beberapa contoh melakukan ini menggunakan atribut model _meta, tetapi bukankah garis bawah di depan meta menunjukkan bahwa atribut _meta adalah atribut pribadi dan tidak boleh diakses secara langsung? ... Karena, misalnya, tata letak _meta dapat berubah di masa mendatang dan bukan API yang stabil?
Apakah _meta merupakan pengecualian untuk aturan ini? Apakah stabil dan siap digunakan atau dianggap praktik yang buruk untuk mengaksesnya? Atau apakah ada fungsi atau cara lain untuk melakukan introspeksi bidang model tanpa menggunakan atribut _meta? Di bawah ini adalah daftar beberapa tautan yang menunjukkan cara melakukan ini menggunakan atribut _meta
Saran apa pun sangat dihargai.
Jawaban:
_meta
bersifat pribadi, tetapi relatif stabil. Ada upaya untuk memformalkannya, mendokumentasikannya, dan menghapus garis bawah, yang mungkin terjadi sebelum 1.3 atau 1.4. Saya membayangkan upaya akan dilakukan untuk memastikan segala sesuatunya kompatibel ke belakang, karena banyak orang telah menggunakannya.Jika Anda sangat khawatir tentang kompatibilitas, tulis fungsi yang menggunakan model dan mengembalikan bidang. Artinya jika ada sesuatu yang berubah di masa depan, Anda hanya perlu mengubah satu fungsi.
Saya yakin ini akan mengembalikan daftar
Field
objek. Untuk mendapatkan nilai setiap bidang dari instance, gunakangetattr(instance, field.name)
.Pembaruan: Kontributor Django sedang mengerjakan API untuk menggantikan objek _Meta sebagai bagian dari Google Summer of Code. Lihat:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api
sumber
model._meta.many_to_many
!django/core/management/commands/loaddata.py
menggunakan _meta untuk menjalankan pohon aplikasi, model, dan bidang. Pola yang bagus untuk diikuti ... dan Anda bisa bertaruh itu adalah "cara resmi"._meta.virtual_fields
_meta
sekarang menjadi API resmi yang didukung (baru di Django 1.8)Saya tahu posting ini cukup lama, tetapi saya hanya ingin memberi tahu siapa pun yang mencari hal yang sama bahwa ada API publik dan resmi untuk melakukan ini:
get_fields()
danget_field()
Pemakaian:
https://docs.djangoproject.com/en/1.8/ref/models/meta/
sumber
get_fields()
docs.djangoproject.com/en/1.10/ref/models/meta/…_meta
?Sekarang ada metode khusus - get_fields ()
Ini menerima dua parameter yang dapat digunakan untuk mengontrol bidang mana yang dikembalikan:
include_parents
Benar secara default. Secara rekursif menyertakan bidang yang ditentukan pada kelas induk. Jika disetel ke False, get_fields () hanya akan mencari bidang yang dideklarasikan secara langsung pada model saat ini. Bidang dari model yang secara langsung mewarisi dari model abstrak atau kelas proxy dianggap lokal, bukan induknya.
include_hidden
Salah secara default. Jika disetel ke True, get_fields () akan menyertakan bidang yang digunakan untuk mendukung fungsionalitas bidang lain. Ini juga akan menyertakan kolom apa pun yang memiliki related_name (seperti ManyToManyField, atau ForeignKey) yang dimulai dengan "+"
sumber
get_fields()
mengembalikan atuple
dan setiap elemen adalahModel field
tipe, yang tidak dapat digunakan secara langsung sebagai string. Jadi,field.name
akan mengembalikan nama fieldmy_model_fields = [field.name for field in MyModel._meta.get_fields()]
Kode di atas akan mengembalikan daftar yang menghubungkan semua nama bidang
Contoh
sumber
Ini adalah sesuatu yang dilakukan oleh Django sendiri saat membangun bentuk dari model. Ini menggunakan atribut _meta, tetapi seperti yang dicatat Bernhard, ini menggunakan _meta.fields dan _meta.many_to_many. Melihat django.forms.models.fields_for_model, berikut adalah bagaimana Anda dapat melakukannya:
sumber
Bidang model yang dimuat oleh _meta dicantumkan di beberapa lokasi sebagai daftar objek bidang masing-masing. Mungkin lebih mudah untuk bekerja dengan mereka sebagai kamus di mana kuncinya adalah nama bidang.
Menurut pendapat saya, ini adalah cara paling irredundan dan ekspresif untuk mengumpulkan dan mengatur objek bidang model:
(Lihat contoh penggunaan di django.forms.models.fields_for_model.)
sumber
Bagaimana dengan yang ini.
sumber
many_to_many
danvirtual_fields
.Sesuai dengan dokumentasi django 2.2 Anda dapat menggunakan:
Untuk mendapatkan semua bidang:
Model._meta.get_fields()
Untuk mendapatkan bidang individu:
Model._meta.get_field('field name')
ex.
Session._meta.get_field('expire_date')
sumber
Jika Anda memerlukan ini untuk situs admin Anda , ada juga
ModelAdmin.get_fields
metode ( dokumen ), yang mengembalikanlist
nama bidangstrings
.Sebagai contoh:
sumber
Cara lain adalah menambahkan fungsi ke model dan bila Anda ingin mengganti tanggal, Anda dapat memanggil fungsi tersebut.
sumber