【发布时间】:2015-09-08 10:41:21
【问题描述】:
我想根据数据库中的username、first_name 和last_name 字段查找用户。
到目前为止我所做的是:
def _build_q_for_field(fieldname, wordlist):
def _param(x):
return {fieldname + '__icontains': x}
return reduce(operator.or_, (Q(**_param(w)) for w in wordlist))
query_string = "Fabian M"
query_words = query_string.strip().split(' ') # ['Fabian', 'M']
qs = User.objects.all()
qs = qs.filter(
_build_q_for_field('username', query_words) |
_build_q_for_field('first_name', query_words) |
_build_q_for_field('last_name', query_words)
)
假设我们有以下非常简单的用户集:
- 用户 1:
first_name = 'Fabian'、last_name = 'Mueller'、username = 'fmueller' - 用户 2:
first_name = 'Fabian'、last_name = 'Schulze'、username = 'fschulze'
上面的代码将返回两个对象,因为所有条件都通过 OR 连接,并且两个用户都拥有first_name = 'Fabian'。但我希望结果集中只有用户 Fabian Mueller,因为单词列表中的第二个单词 (M) 不包含在第二个结果中。
你有一个聪明的主意如何存档吗?在过滤方法中使用 AND 而不是 OR 组合 Q 在上面的示例中确实有效,但是如果单词列表仅包含一个单词并且会立即排除用户名不匹配的结果,例如在上面的例子。
你有一个聪明的解决方案如何处理这个问题吗?提前致谢!
【问题讨论】: