8on*_*ne6 17 python sql django django-queryset
说我有一个模型:
Class Person(models.Model):
firstname = models.CharField()
lastname = models.CharField()
birthday = models.DateField()
# etc...
Run Code Online (Sandbox Code Playgroud)
并说我有一个2个名字的列表:first_list = ['Bob', 'Rob']我有一个2个姓氏的列表:last_list = ['Williams', 'Williamson'].然后,如果我想选择名字所在的每个人,first_list我可以运行:
Person.objects.filter(firstname__in=first_list)
Run Code Online (Sandbox Code Playgroud)
如果我想选择其姓氏的所有人last_list,我可以这样做:
Person.objects.filter(lastname__in=last_list)
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.如果我想同时运行这两个限制,这很容易......
Person.objects.filter(firstname__in=first_list, lastname__in=last_list)
Run Code Online (Sandbox Code Playgroud)
如果我想进行or样式搜索而不是and样式搜索,我可以用Q对象来做:
Person.objects.filter(Q(firstname__in=first_list) | Q(lastname__in=last_name))
Run Code Online (Sandbox Code Playgroud)
但我想到的是一些更微妙的东西.如果我只想返回一个返回名字和姓氏的特定组合的查询集,该怎么办?即我要返回Person的哪些对象(Person.firstname, Person.lastname)是zip(first_names, last_names).即我想找回任何一个名叫鲍勃威廉姆斯或罗伯威廉姆森的人(但不是任何一个名叫鲍勃威廉姆森或罗布威廉姆斯).
在我的实际使用情况,first_list并last_list就都有〜100元.
目前,我需要在Django应用程序中解决此问题.但我也很好奇在更一般的SQL上下文中处理这个问题的最佳方法.
谢谢!(如果我能说清楚的话,请告诉我.)
bru*_*ers 21
除了一个大的OR子句,我没有看到太多的解决方案:
import operator
from itertools import izip
query = reduce(
operator.or_,
(Q(firstname=fn, lastname=ln) for fn, ln in izip(first_list, last_list))
)
Person.objects.filter(query)
Run Code Online (Sandbox Code Playgroud)
bruno的答案有效,但对我来说却很肮脏-在Python级别和SQL级别(OR的大连接)都如此。至少在MySQL中,您可以使用以下SQL语法:
SELECT id FROM table WHERE (first_name, last_name) IN
(('John','Doe'),('Jane','Smith'),('Bill','Clinton'))
Run Code Online (Sandbox Code Playgroud)
Django的ORM没有提供直接的方法来执行此操作,因此我使用原始SQL:
User.objects.raw('SELECT * FROM table WHERE (first_name, last_name) IN %s',
[ (('John','Doe'),('Jane','Smith'),('Bill','Clinton')) ])
Run Code Online (Sandbox Code Playgroud)
(这是一个具有一个元素的列表,与查询中的单个%s匹配。该元素是可重复的元组,因此%s将转换为SQL元组列表)。
笔记:
| 归档时间: |
|
| 查看次数: |
6365 次 |
| 最近记录: |