我可以按此类条件过滤查询吗?像
这样的东西Model.objects.filter(department__is_contained=x).values_list('department')
其中
x = 'AAA-BBB-CCC-DDD'
我的结果应该显示
之类的内容 ['AAA', 'AAA-BBB-CCC', 'BBB-CCC', 'AAA-BBB-CCC-DDD', None]
答案 0 :(得分:1)
不,没有。您想要执行的SQL看起来像这样:
SELECT *
FROM model
WHERE 'AAA-BBB-CCC-DDD' like '%' + model.department + '%'
Django目前不支持左侧的过滤条件。可以使用custom lookups使用django 1.7实现自己的reverse_contains查找。
class ReverseContains(Lookup):
lookup_name = 'rcontains'
def as_sql(self, qn, connection):
# untested! you'll have to validate this
lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection)
# note we're putting the rhs sql and params on the lhs
params = rhs_params + lhs_params
return "%s LIKE '%%' + %s + '%%' " % (rhs, lhs), params
from django.db.models.fields import CharField
CharField.register_lookup(ReverseContains)
并像这样使用它:
x = 'AAA-BBB-CCC-DDD'
Model.objects.filter(department__rcontains=x).values_list('department')
或者您可以使用.extra(where=)直接在SQL中为该一个查询实现搜索。
答案 1 :(得分:0)
这是一个单线解决方案:
import operator
from django.db.models import Q
x = 'AAA-BBB-CCC-DDD'
User.objects.filter(reduce(operator.or_, (Q(department__contains=y) for y in x.split('-')))).values_list('department', flat=True)
# Result will be list of 'department' fields, that contains
# "AAA" or "BBB" or "CCC" or "DDD"
可能很难理解,所以这里有一个更详细的代码变体:
total_filter_q = Q()
for y in x.split("-"):
total_filter_q |= Q(department__contains=y)
# total_filter_q now represent this:
# Q(department__contains="AAA") | Q(department__contains="BBB") | Q(department__contains="CCC") | Q(department__contains="DDD")
User.objects.filter(total_filter_q).values_list('department', flat=True)
结果与单行解决方案相同。
以下是一些有用的链接: