回答

收藏

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

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

说我有一个模型:
" _' @' v6 w" U. e; d* k0 sClass Person(models.Model):0 I. H. ?% V0 d% y: |5 [3 \" h
    firstname = models.CharField()
8 l  ~2 O0 @0 c* ]/ w    lastname = models.CharField()# |* R, [- U8 U6 j) c6 Y% O
    birthday = models.DateField()
4 n" w6 W6 a" Z' I    # etc.... m, X0 }1 a- e
并说我有2个姓氏列表:first_list = ['Bob', 'Rob']我有2个姓氏列表:last_list = ['Williams',  @: i1 c0 l/ q2 x  [' \1 V
'Williamson']。然后,如果我想选择名字在其中的每个人,first_list我可以运行:
  l6 Q; ^7 B  B' _3 T$ T5 t0 IPerson.objects.filter(firstname__in=first_list)
6 s$ O* I6 ]8 N7 W% y8 z- g如果我想选择姓氏在的所有人last_list,我可以这样做:
; D' B  \0 g- @9 lPerson.objects.filter(lastname__in=last_list). u$ @! A1 C3 E) f1 g  D
到目前为止,一切都很好。如果我想同时运行这两个限制,那很容易…& V' L% X" j- a# g
Person.objects.filter(firstname__in=first_list, lastname__in=last_list)
/ b& O- P- s9 P, N% k. F如果我想进行or样式搜索而不是and样式搜索,则可以使用Q对象:
5 i5 }! F, I5 x3 S* gPerson.objects.filter(Q(firstname__in=first_list) | Q(lastname__in=last_name))* Z1 L) X8 f$ F) i& g6 k) S$ i
但是我的想法有些微妙。如果我只想返回一个返回名字和姓氏特定组合的查询集怎么办?即我想返回in中的Person对象。也就是说,我想找回叫鲍勃·威廉姆斯或罗伯·威廉姆森的人(但不要叫鲍勃·威廉姆森或罗伯·威廉姆斯的人)。
: B' x. T" s; t5 a4 J: @3 K(Person.firstname, Person.lastname)``zip(first_names, last_names). a* Y0 K1 h, l/ M" _! g
在我的实际使用情况,first_list并last_list就都有?100元。2 x: \! T* j0 F' s
目前,我需要在Django应用中解决此问题。但是我也对在更通用的SQL上下文中处理此问题的最佳方法感到好奇。$ `. \. x- {- x
谢谢!(并且请让我知道是否可以澄清任何事情。)
; z* O0 ^- d7 m- K/ x; O                $ F( c9 k2 N8 G" \3 v# h1 F
解决方案:) a, t. B! S5 F( F4 `; h
               
1 X; Q0 r& [/ n0 Z+ N
/ x! o0 T4 k9 C, ~3 y
& S" {$ z. c3 Q9 I0 _                除了一个大的OR子句,我看不到很多解决方案:8 P) j3 k: }; Z" _6 @, s
import operator  m  P2 D# ~1 M& f5 q5 A! Q
from itertools import izip
* x; v$ C: k: {1 H$ C7 qquery = reduce(! ^) _7 {9 P) H* U
    operator.or_,
  x+ j% Z& I& k  G" x0 i" ]$ r    (Q(firstname=fn, lastname=ln) for fn, ln in izip(first_list, last_list))! q& v" t2 u. u$ \9 [
    )
0 j: c2 [, T/ O' j$ @4 GPerson.objects.filter(query)
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则