Saya mencoba membuat templat dasar untuk menampilkan nilai bidang instance yang dipilih, bersama dengan nama mereka. Anggap saja sebagai output standar dari nilai instance dalam format tabel, dengan nama bidang (verbose_name khusus jika ditentukan pada bidang) di kolom pertama dan nilai bidang itu di kolom kedua.
Misalnya, katakanlah kita memiliki definisi model berikut:
class Client(Model):
name = CharField(max_length=150)
email = EmailField(max_length=100, verbose_name="E-mail")
Saya ingin itu menjadi output dalam template seperti itu (asumsikan sebuah instance dengan nilai yang diberikan):
Field Name Field Value
---------- -----------
Name Wayne Koorts
E-mail waynes@email.com
Apa yang saya coba capai adalah mampu mengirimkan contoh model ke templat dan dapat mengulanginya secara dinamis dalam templat, sesuatu seperti ini:
<table>
{% for field in fields %}
<tr>
<td>{{ field.name }}</td>
<td>{{ field.value }}</td>
</tr>
{% endfor %}
</table>
Apakah ada cara rapi, "disetujui Django" untuk melakukan ini? Sepertinya ini tugas yang sangat umum, dan saya harus sering melakukannya untuk proyek khusus ini.
sumber
Anda dapat menggunakan serializer to-python Django to-python .
Masukkan saja kode berikut ke dalam pandangan Anda:
Dan kemudian di templat:
Keuntungan besarnya adalah kenyataan bahwa ia menangani bidang hubungan.
Untuk subset bidang coba:
sumber
verbose_name
bidang dilewatkan?Akhirnya menemukan solusi yang bagus untuk ini di milis dev :
Dalam tampilan tambahkan:
dalam templat tambahkan:
sumber
FooForm
adalahModelForm
, bukankah lebih mudah untuk hanya melakukanFooForm(instance=Foo.objects.get(pk=object_id)))
:?Mengingat rilis Django 1.8 (dan formalisasi API Model _meta , saya pikir saya akan memperbarui ini dengan jawaban yang lebih baru.
Dengan asumsi model yang sama:
Django <= 1.7
Django 1.8+ (Model Formal _meta API)
Dalam contoh di bawah ini, kami akan menggunakan metode formal untuk mengambil semua instance lapangan dari model melalui
Client._meta.get_fields()
:Sebenarnya, telah menarik perhatian saya bahwa di atas sedikit berlebihan untuk apa yang dibutuhkan (saya setuju!). Sederhana lebih baik daripada kompleks. Saya meninggalkan referensi di atas untuk. Namun, untuk ditampilkan dalam templat, metode terbaik adalah menggunakan ModelForm dan mengirimkan instance. Anda bisa mengulangi formulir (setara dengan mengulangi setiap bidang formulir) dan menggunakan atribut label untuk mengambil verbose_name dari bidang model, dan menggunakan metode nilai untuk mengambil nilai:
Sekarang, kami merender bidang dalam templat:
sumber
Berikut pendekatan lain menggunakan metode model. Versi ini menyelesaikan bidang daftar pilihan / pilihan, melompati bidang kosong, dan memungkinkan Anda mengecualikan bidang tertentu.
Kemudian di templat Anda:
sumber
except User.DoesNotExist:
?_meta.get_fields()
sampai saya bisa mengujinya.Ok, saya tahu ini agak terlambat, tetapi karena saya menemukan ini sebelum menemukan jawaban yang benar, maka mungkin orang lain.
Dari django docs :
sumber
ordering = ['-id']
diclass Meta:
objek Anda dimodels.py
. 2. kemudian gunakanBlog.objects.filter(name__startswith='Beatles').values()[0]
model
objek, maka Anda akan menekan database lagi hanya untuk mendapatkan bidang. Ada jalan lain?Anda dapat menggunakan
values()
metode aqueryset
, yang mengembalikan kamus. Lebih lanjut, metode ini menerima daftar bidang yang akan di-subset. Thevalues()
Metode tidak akan bekerja denganget()
, sehingga Anda harus menggunakanfilter()
(mengacu pada API QuerySet ).Dalam
view
...Dalam
detail.html
...Untuk koleksi instance yang dikembalikan oleh filter:
Dalam detail.html ...
sumber
table
, jadi saya perlu masing-masingkey
dalamth
. Bagaimana saya melakukannya tanpa loop? Ambil saja instance objek dan lakukan iterasi untukkey
itu? Saat ini saya secara terpisah lulusmodel_to_dict(Model())
untukth
, tetapi saya pikir itu adalah objek objek yang tidak perlu.get_object
tampilan detail (rusak karena keterbatasan kode sebaris pada komentar, dan tidak merasa seperti ini sudah cukup untuk jawabannya sendiri mengingat seberapa jenuh utas ini):def get_object(self, **kwargs): obj = super().get_object(**kwargs) obj = obj.__class__.objects.filter(pk=obj.pk).values()[0] return obj
obj.get_absolute_url
ke daftar ini tanpa menduplikasi baris?Saya menggunakan https://stackoverflow.com/a/3431104/2022534 tetapi menggantikan model_to_dict Django () dengan ini untuk dapat menangani ForeignKey:
Harap dicatat bahwa saya telah menyederhanakannya sedikit dengan menghapus bagian asli yang tidak saya butuhkan. Anda mungkin ingin mengembalikannya.
sumber
Anda dapat meminta formulir melakukan pekerjaan untuk Anda.
Kemudian di templat:
sumber
DetailView
) bekerja dengan baik untuk saya. Namun, Anda mungkin ingin menggunakanfield.label
bukanfield.name
.Harus benar-benar ada cara bawaan untuk melakukan ini. Saya menulis utilitas ini
build_pretty_data_view
yang mengambil objek model dan contoh bentuk (formulir berdasarkan model Anda) dan mengembalikan aSortedDict
.Manfaat untuk solusi ini meliputi:
SortedDict
.exclude()
daftar nama bidang untuk mengecualikan bidang tertentu.Meta: exclude()
, tetapi Anda masih ingin mengembalikan nilai, lalu tambahkan bidang itu keappend()
daftar opsional .Untuk menggunakan solusi ini, pertama tambahkan file / fungsi ini di suatu tempat, lalu impor ke
views.py
.utils.py
Jadi sekarang di Anda,
views.py
Anda mungkin melakukan sesuatu seperti iniSekarang di
my-template.html
templat Anda, Anda dapat mengulangi data seperti ...Semoga berhasil. Semoga ini bisa membantu seseorang!
sumber
Di bawah ini milik saya, terinspirasi oleh shacker's
get_all_fields
. Ia mendapatkan dict dari satu contoh model, jika menemukan bidang relasi, lalu menugaskan nilai bidang sebuah dict secara rekursif.Fungsi ini terutama digunakan untuk membuang contoh model ke data json:
sumber
Alih-alih mengedit setiap model saya akan merekomendasikan untuk menulis satu tag templat yang akan mengembalikan semua bidang model yang diberikan.
Setiap objek memiliki daftar bidang
._meta.fields
.Setiap objek bidang memiliki atribut
name
yang akan mengembalikan nama dan metodevalue_to_string()
yang disertakan dengan model Andaobject
akan mengembalikan nilainya.Sisanya sesederhana seperti yang dikatakan dalam dokumentasi Django .
Berikut adalah contoh saya bagaimana templatetag ini terlihat:
sumber
Ya itu tidak cantik, Anda harus membuat bungkus sendiri. Lihatlah aplikasi databrowse bawaan , yang memiliki semua fungsi yang Anda butuhkan.
sumber
Ini dapat dianggap sebagai retasan tetapi saya telah melakukan ini sebelum menggunakan modelform_factory untuk mengubah contoh model menjadi formulir.
Kelas Form memiliki lebih banyak informasi di dalamnya yang super mudah untuk diulang dan akan melayani tujuan yang sama dengan mengorbankan overhead yang sedikit lebih banyak. Jika ukuran yang Anda tentukan relatif kecil, saya pikir dampak kinerja akan diabaikan.
Satu keuntungan di samping kenyamanan tentu saja adalah bahwa Anda dapat dengan mudah mengubah tabel menjadi datagrid yang dapat diedit di kemudian hari.
sumber
Saya telah datang dengan metode berikut, yang bekerja untuk saya karena dalam setiap kasus model akan memiliki ModelForm yang terkait dengannya.
Berikut ini kutipan dari template yang saya gunakan untuk tampilan khusus ini:
Yang menyenangkan tentang metode ini adalah bahwa saya dapat memilih berdasarkan template-by-template urutan di mana saya ingin menampilkan label bidang, menggunakan tuple yang diteruskan ke GetModelData dan menentukan nama bidang. Ini juga memungkinkan saya untuk mengecualikan bidang tertentu (misalnya kunci asing Pengguna) karena hanya nama bidang yang dilewatkan melalui tuple yang dimasukkan ke dalam kamus akhir.
Saya tidak akan menerima ini sebagai jawaban karena saya yakin seseorang dapat menemukan sesuatu yang lebih "Djangonic" :-)
Pembaruan: Saya memilih ini sebagai jawaban akhir karena ini adalah yang paling sederhana dari yang diberikan yang melakukan apa yang saya butuhkan. Terima kasih kepada semua orang yang berkontribusi jawaban.
sumber
Solusi Django 1.7 untuk saya:
Ada variabel yang tepat untuk pertanyaan, tetapi Anda harus dapat membedah contoh ini
Kuncinya di sini adalah cukup banyak menggunakan
.__dict__
modelviews.py :
templat :
di templat saya menggunakan filter untuk mengakses bidang di dict
filter.py :
sumber
Saya menggunakan ini, https://github.com/miracle2k/django-tables .
sumber
Pendekatan ini menunjukkan bagaimana menggunakan kelas seperti ModelForm django dan tag templat seperti {{form.as_table}}, tetapi memiliki semua tabel yang terlihat seperti output data, bukan formulir.
Langkah pertama adalah untuk subclass widget TextInput django:
Kemudian saya subclassed django's ModelForm untuk menukar keluar widget default untuk versi hanya baca:
Itulah satu-satunya widget yang saya butuhkan. Tetapi seharusnya tidak sulit untuk memperluas ide ini ke widget lain.
sumber
Hanya edit dari @wonder
Biarkan Django menangani semua bidang lain selain bidang terkait. Saya merasa itu lebih stabil
sumber
Lihatlah aplikasi django-etc . Memiliki
model_field_verbose_name
tag templat untuk mendapatkan nama verbose bidang dari templat: http://django-etc.rtfd.org/en/latest/models.html#model-field-field-template-tagssumber
Saya baru saja menguji sesuatu seperti ini di shell dan tampaknya melakukan tugasnya:
Perhatikan bahwa jika Anda ingin representasi str () untuk objek asing, Anda harus mendefinisikannya dalam metode str mereka . Dari itu Anda memiliki nilai untuk objek. Kemudian Anda dapat membuat semacam template atau apa pun.
sumber
Django> = 2.0
Tambahkan
get_fields()
ke Andamodels.py
:Kemudian panggil seperti
object.get_fields
pada Andatemplate.html
:sumber
sumber