Dari sebuah contoh, Anda dapat melihat beberapa filter ATAU kueri:
Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Misalnya, ini menghasilkan:
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
Namun, saya ingin membuat filter kueri ini dari daftar. Bagaimana cara melakukannya?
misalnya [1, 2, 3] -> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
Article.objects.filter(pk__in=[1, 2, 3])
dalam django modern, tetapi pertanyaannya masih relevan jika Anda ingin melakukan sesuatu yang lebih mahir dengan OR'ing objek Q bersama-sama.Jawaban:
Anda dapat merangkai kueri Anda sebagai berikut:
sumber
Untuk membangun kueri yang lebih kompleks, ada juga opsi untuk menggunakan konstanta objek Q () bawaan Q.OR dan Q.AND bersama dengan metode add () seperti:
sumber
q_objects |= Q(pk=item)
list
kebetulan kosong Anda akan mengembalikan yang setaraArticle.objects.all()
. Mudah untuk dikurangi dengan kembaliArticle.objects.none()
untuk tes itu.q_objects
denganQ(id__in=[])
. Itu akan selalu gagal kecuali ORed dengan sesuatu dan pengoptimal kueri akan menanganinya dengan baik.Cara yang lebih singkat untuk menulis jawaban Dave Webb menggunakan fungsi pengurangan python :
sumber
functools.reduce
. sumberoperator.or_
sebagai pengganti lambda.sumber
operator
asalnya?Mungkin lebih baik menggunakan pernyataan sql IN.
Lihat referensi api queryset .
Jika Anda benar-benar perlu membuat kueri dengan logika dinamis, Anda dapat melakukan sesuatu seperti ini (jelek + tidak diuji):
sumber
query |= Q(field=cond)
Lihat dokumennya :
Perhatikan bahwa metode ini hanya berfungsi untuk pencarian kunci utama, tetapi tampaknya itulah yang Anda coba lakukan.
Jadi yang Anda inginkan adalah:
sumber
Jika kita ingin mengatur secara terprogram bidang db apa yang ingin kita kueri:
sumber
Solusi yang digunakan
reduce
danor_
operator untuk memfilter dengan mengalikan bidang.ps
f
adalah format string literal baru. Itu diperkenalkan di python 3.6sumber
Anda dapat menggunakan operator | = untuk secara terprogram memperbarui kueri menggunakan objek Q.
sumber
Yang ini untuk daftar pk dinamis:
sumber
q = Q()
bukanq = None
, kemudian menghapusif q is None
klausul - sedikit kurang efisien namun dapat menghapus tiga baris kode. (Q kosong kemudian digabungkan saat kueri dijalankan.)Pilihan lain Saya tidak menyadari sampai saat ini -
QuerySet
juga menimpa&
,|
,~
, dll, operator. Jawaban lain bahwa objek OR Q adalah solusi yang lebih baik untuk pertanyaan ini, tetapi demi kepentingan / argumen, Anda dapat melakukan:str(q.query)
akan mengembalikan satu kueri dengan semua filter diWHERE
klausa.sumber
Untuk loop:
Mengurangi:
Keduanya setara dengan
Article.objects.filter(pk__in=values)
Penting untuk mempertimbangkan apa yang Anda inginkan saat
values
kosong. Banyak jawaban denganQ()
nilai awal akan mengembalikan semuanya .Q(pk__in=[])
adalah nilai awal yang lebih baik. Ini adalah objek Q yang selalu gagal yang ditangani dengan baik oleh pengoptimal (bahkan untuk persamaan kompleks).Jika Anda ingin mengembalikan semuanya saat
values
kosong, Anda harus DAN dengan~Q(pk__in=[])
untuk memastikan perilaku itu:Penting untuk diingat bahwa
Q()
bukan apa - apa , bukan objek Q yang selalu berhasil. Operasi apa pun yang melibatkannya hanya akan menjatuhkannya sepenuhnya.sumber
mudah ..
dari django.db.models import Q import you model args = (Q (visibility = 1) | (Q (visibility = 0) & Q (user = self.user))) #Tuple parameter = {} #dic order = 'create_at' limit = 10
sumber