我的模型看起来像这样:
uri
-----
1@domainXY
2@domainYZ
3@domainZK
我想将此uris的用户名部分与某些列表相匹配。因此,如果uri没有@domain部分,我会输入:
L = ['1', '2']
model.objects.filter(uri__in=L)
但是如何忽略此查询中的域部分?所以我需要的是这样的事情(我明白这不是django-way如何做到这一点,而只是为了解释我正在尝试做的事情):
L = ['1', '2']
model.objects.filter(strip_domain_part_with_at(uri)__in=L)
我不能也不想做任何原始查询。
答案 0 :(得分:2)
根据您的数据,您可以使用__startswith
:
https://docs.djangoproject.com/en/dev/ref/models/querysets/#startswith
但是,如果您的数字前缀超出单个数字(并且不是零填充到常量长度),那么这样的简单字符串比较将无法正常工作。 (即1
,10
,104
所有'始于' 1
)
您可以尝试__regex
查询:
https://docs.djangoproject.com/en/dev/ref/models/querysets/#regex
例如
model.objects.filter(uri__regex==r'^(%s)@.+' % '|'.join(L))
您应该对数据的性能进行分析,因为正则表达式的使用可能很慢(即使支持__regex
的数据库后端本身可能无法使用索引进行正则表达式查询,因此会执行全表扫描)。
可能更好的方法是将部件存储在@
之前的附加模型字段中,以便您可以对其运行更简单的查询。
答案 1 :(得分:1)
from django... import Q
qry = " | ".join(["Q(uri__startswith ='%s@')"%v for v in L])
model.objects.filter(eval(qry))
可能有比使用eval
更好的方法