Saya telah mendefinisikan User
kelas yang (akhirnya) mewarisi dari models.Model
. Saya ingin mendapatkan daftar semua bidang yang ditentukan untuk model ini. Sebagai contoh phone_number = CharField(max_length=20)
,. Pada dasarnya, saya ingin mengambil apa pun yang diwarisi dari Field
kelas.
Saya pikir saya dapat mengambil ini dengan mengambil keuntungan dari inspect.getmembers(model)
, tetapi daftar yang dikembalikan tidak mengandung bidang-bidang ini. Sepertinya Django sudah menguasai kelas dan menambahkan semua atribut sihirnya dan menghapus apa yang sebenarnya telah didefinisikan. Jadi ... bagaimana saya bisa mendapatkan bidang ini? Mereka mungkin memiliki fungsi untuk mengambil mereka untuk keperluan internal mereka sendiri?
django
django-models
Mpen
sumber
sumber
Jawaban:
Karena sebagian besar jawaban sudah usang, saya akan mencoba memperbarui Anda di Django 2.2 Di sini posting - aplikasi Anda (posting, blog, toko, dll)
1) Dari tautan model : https://docs.djangoproject.com/en/2.2/ref/models/meta/
Perhatikan bahwa:
Juga akan mendapatkan beberapa hubungan, yang untuk mantan. Anda tidak dapat ditampilkan dalam tampilan.
Seperti dalam kasus saya:
dan
2) Dari contoh
3) Dari model induk
Anggaplah kita memiliki Post sebagai model induk dan Anda ingin melihat semua bidang dalam daftar, dan memiliki bidang induk untuk hanya-baca dalam mode Edit.
sumber
clean_field_names = [str(h).split('.')[2].replace("_", " ").title() for h in all_fields]
all_fields = bp._meta.fields
Versi Django 1.8 dan yang lebih baru:
Anda harus menggunakan
get_fields()
:The
get_all_field_names()
Metode ini usang mulai dari Django 1.8 dan akan dihapus dalam 1.10 .Halaman dokumentasi yang ditautkan di atas memberikan implementasi yang sepenuhnya kompatibel dengan mundur
get_all_field_names()
, tetapi untuk sebagian besar tujuan contoh sebelumnya harus bekerja dengan baik.Versi Django sebelum 1.8:
Itu harus melakukan trik.
Itu membutuhkan contoh model yang sebenarnya. Jika semua yang Anda miliki adalah subkelas dari
django.db.models.Model
, maka Anda harus meneleponmyproject.myapp.models.MyModel._meta.get_all_field_names()
sumber
model._meta.fields
meskipun, dan nama mereka dapat dipulihkan denganfield.name
tampaknya. Saya hanya berharap ini adalah cara paling stabil untuk mengambil info ini :)django.db.models.Model
. Saya akan menggali dan melihat apa yang bisa saya temukan_meta
atribut adalah satu-satunya cara ... Selain mencari_meta.many_to_many
bidang ManyToMany!The
get_all_related_fields()
Metode yang disebutkan di sini telah usang dalam 1,8 . Mulai sekarangget_fields()
.sumber
Saya menemukan menambahkan ini ke model Django cukup membantu:
Ini memungkinkan Anda melakukan:
sumber
django.db.models.fields.related.RelatedObjectDoesNotExist: CustomModel has no custom_attribute.
ForeignKey
bekerja dengan baik untukku. Meskipun demikian, secara diam-diam menangkap semua pengecualian adalah anti-pola. Jauh lebih baik untuk ditangkapAttributeError
, atau setidaknya mencatat bahwa beberapa pengecualian ditelan diam-diam.self._meta.get_all_field_names()
telah disusutkan dan dihapus. Anda dapat menggunakan sesuatu sepertifor field in self._meta.get_fields()
dan kemudianyield (field.name, field.value_from_object(self))
Ini caranya. Saya hanya mengujinya di Django 1.7.
Model._meta.local_fields
tidak mengandung bidang banyak ke banyak. Anda harus menggunakannyaModel._meta.local_many_to_many
.sumber
Tidak jelas apakah Anda memiliki turunan dari kelas atau kelas itu sendiri dan mencoba untuk mengambil bidang, tetapi bagaimanapun, pertimbangkan kode berikut
Menggunakan contoh
Menggunakan kelas
sumber
Ini berhasil untuk saya
django==1.11.8
sumber
MyModel._meta.get_all_field_names()
itu ditinggalkan beberapa versi kembali dan dihapus di Django 1.10.Berikut saran yang kompatibel dari belakang :
sumber
Hanya untuk menambahkan, saya menggunakan objek mandiri, ini bekerja untuk saya:
sumber
Setidaknya dengan Django 1.9.9 - versi yang saya gunakan saat ini -, perhatikan bahwa
.get_fields()
sebenarnya juga "menganggap" model asing sebagai bidang, yang mungkin bermasalah. Katakanlah Anda memiliki:Karena itu
sementara, seperti yang ditunjukkan oleh @Rockallite
sumber
Jadi sebelum saya menemukan posting ini, saya berhasil menemukan ini berfungsi.
Ini berfungsi sama seperti
Saya tidak yakin apa bedanya dalam hasil, jika ada. Saya menjalankan loop ini dan mendapatkan output yang sama.
sumber
Mengapa tidak menggunakannya saja:
Contoh output:
sumber