Diberi kelas:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=20)
Apakah mungkin, dan jika demikian caranya, memiliki QuerySet yang memfilter berdasarkan argumen dinamis? Sebagai contoh:
# Instead of:
Person.objects.filter(name__startswith='B')
# ... and:
Person.objects.filter(name__endswith='B')
# ... is there some way, given:
filter_by = '{0}__{1}'.format('name', 'startswith')
filter_value = 'B'
# ... that you can run the equivalent of this?
Person.objects.filter(filter_by=filter_value)
# ... which will throw an exception, since `filter_by` is not
# an attribute of `Person`.
python
django
django-models
Brian M. Hunt
sumber
sumber
Contoh sederhana:
Dalam aplikasi survei Django, saya ingin daftar pilih HTML yang menunjukkan pengguna terdaftar. Tetapi karena kami memiliki 5.000 pengguna terdaftar, saya membutuhkan cara untuk memfilter daftar itu berdasarkan kriteria kueri (seperti hanya orang yang menyelesaikan lokakarya tertentu). Agar elemen survei dapat digunakan kembali, saya perlu orang yang membuat pertanyaan survei untuk dapat melampirkan kriteria tersebut untuk pertanyaan itu (tidak ingin menyulitkan kueri kode ke dalam aplikasi).
Solusi yang saya buat bukanlah 100% user friendly (membutuhkan bantuan dari orang teknologi untuk membuat kueri) tetapi itu memecahkan masalah. Saat membuat pertanyaan, editor dapat memasukkan kamus ke dalam bidang khusus, misalnya:
String itu disimpan dalam database. Dalam kode tampilan, ia kembali sebagai
self.question.custom_query
. Nilai itu adalah string yang terlihat seperti kamus. Kami mengubahnya kembali menjadi kamus nyata dengan eval () dan kemudian memasukkannya ke queryset dengan ** kwargs:sumber
eval()
impor pengguna adalah ide yang buruk, bahkan jika Anda sepenuhnya mempercayai pengguna Anda. Bidang JSON akan menjadi ide yang lebih baik di sini.Django.db.models.Q persis seperti yang Anda inginkan dengan cara Django.
sumber
Q(**filters)
, jika Anda ingin membangun objek Q secara dinamis, Anda dapat menempatkannya dalam daftar dan menggunakan.filter(*q_objects)
, atau menggunakan operator bitwise untuk menggabungkan objek Q.Bentuk pencarian yang sangat kompleks biasanya menunjukkan bahwa model yang lebih sederhana sedang mencoba menggali jalan keluarnya.
Bagaimana, tepatnya, apa yang Anda harapkan untuk mendapatkan nilai untuk nama kolom dan operasi? Di mana Anda mendapatkan nilai-nilai
'name'
suatu'startswith'
?Bentuk "pencarian"? Anda akan - apa? - pilih nama dari daftar nama? Pilih operasi dari daftar operasi? Sementara terbuka, kebanyakan orang menemukan ini membingungkan dan sulit digunakan.
Berapa kolom yang memiliki filter seperti itu? 6? 12? 18?
Tombol filter khusus. Tunggu ... Begitulah cara kerja admin Django. Filter khusus diubah menjadi tombol. Dan analisis yang sama seperti di atas berlaku. Beberapa filter masuk akal. Sejumlah besar filter biasanya berarti jenis pelanggaran bentuk normal pertama.
Banyak bidang serupa sering berarti seharusnya ada lebih banyak baris dan lebih sedikit bidang.
sumber