回答

收藏

Django过滤器对多列值的“组合”查询集

技术问答 技术问答 180 人阅读 | 0 人回复 | 2023-09-14

说我有一个模型:
( p9 t, N2 u) k" ~* ?7 J# eClass Person(models.Model):
+ l3 G6 H$ R' M7 |4 O4 I+ g    firstname = models.CharField()/ J! ]# Y/ B* x" \3 U& N
    lastname = models.CharField()
% x1 M: t5 s1 ~' y* O2 K( W    birthday = models.DateField()
# ?, n; Z8 @( ]    # etc...4 q5 y/ o3 \" ^
并说我有2个姓氏列表:first_list = ['Bob', 'Rob']我有2个姓氏列表:last_list = ['Williams',2 l2 n) A+ d) c0 i
'Williamson']。然后,如果我想选择名字在其中的每个人,first_list我可以运行:3 I% W- U( L9 z2 q/ c$ @" c$ ]& u
Person.objects.filter(firstname__in=first_list)/ G. K1 g- ^/ v2 C  S$ c
如果我想选择姓氏在的所有人last_list,我可以这样做:! g: P9 f7 h. N
Person.objects.filter(lastname__in=last_list)/ \. F8 L# I; V; y3 K2 j1 C
到目前为止,一切都很好。如果我想同时运行这两个限制,那很容易…
4 Z8 P  [  F+ w1 G3 ~7 DPerson.objects.filter(firstname__in=first_list, lastname__in=last_list)! K7 O" p1 R' \4 {* a
如果我想进行or样式搜索而不是and样式搜索,则可以使用Q对象:4 f  k( i: _  ]' C
Person.objects.filter(Q(firstname__in=first_list) | Q(lastname__in=last_name))4 A6 l8 e; \7 e! |$ ?6 V% t
但是我的想法有些微妙。如果我只想返回一个返回名字和姓氏特定组合的查询集怎么办?即我想返回in中的Person对象。也就是说,我想找回叫鲍勃·威廉姆斯或罗伯·威廉姆森的人(但不要叫鲍勃·威廉姆森或罗伯·威廉姆斯的人)。
" Y; E* O$ u3 C$ M(Person.firstname, Person.lastname)``zip(first_names, last_names), z' d# X- n& @4 z
在我的实际使用情况,first_list并last_list就都有?100元。- |! u1 m% L, b4 z$ U
目前,我需要在Django应用中解决此问题。但是我也对在更通用的SQL上下文中处理此问题的最佳方法感到好奇。
; v9 i( @! o* b谢谢!(并且请让我知道是否可以澄清任何事情。)! G$ `* ~; {8 u( J
               
  e3 ?% Z5 [( P- \- p  G0 D0 ?9 b1 L解决方案:
8 g7 Q9 c. d/ F2 r; U               
; t+ O. ~; R9 x! E, ]/ }
6 e: F) J: h1 e0 C1 L! e9 f% E: s! S4 n2 \" \" [2 v+ U% @+ T4 a
                除了一个大的OR子句,我看不到很多解决方案:
/ R3 O! i6 l' c" x: m& ~import operator- k- [" K1 g  J# {
from itertools import izip
* t6 z: \* v, L' a1 u! _query = reduce(
3 D; Z5 i2 w- y- o. T    operator.or_,
* t& N; l5 e' t( Y    (Q(firstname=fn, lastname=ln) for fn, ln in izip(first_list, last_list)). w* r: m0 ~2 G  G4 x7 a; X6 g
    )
( U7 I6 y4 f: z, MPerson.objects.filter(query)
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则