如何为 django Q 对象动态加入多个参数
Posted
技术标签:
【中文标题】如何为 django Q 对象动态加入多个参数【英文标题】:How to join multiple params dynamically for django Q object 【发布时间】:2015-12-10 15:26:27 【问题描述】:我正在尝试在 django sqlite db 中实现搜索。
我得到了一个未知长度的参数列表,这些参数都应该与“LIKE”匹配。这意味着我想要所有与至少一个参数匹配的对象。
正如我从 django 文档中看到的那样,我可以通过使用 Q 对象来实现这一点。
例子:
Students.objects.get(
Q(name_contains='franz') |
Q(birthdate_date=date(2005, 5, 2) |
Q(param3_contains='lorem'
)
现在我的问题是,我如何处理它以加入从 params 创建的所有 Q 对象作为参数传递给 objects.get()。我找不到任何关于此的内容。
这里的另一个问题是处理几种不同的字段查找类型。
感谢您提供的任何建议、帮助或帮助链接。谢谢。
【问题讨论】:
不清楚您所说的“加入 Q 对象”是什么意思,如果您想将它们组合在一起,您可以使用&
。此外,您的示例似乎具有不正确的字段查找语法,它应该类似于带有两个下划线的 name__contains
。
我的意思是我不知道我得到了哪些参数。所以它可以是 2、3 或 7 个参数。我不得不遍历它们,将它们放入 Q 对象中,然后将它们作为参数传递给我的 get 函数。但我不知道如何将这些论点与 | 结合在一起。所以我明确地想使用 OR。
查看我在此线程中对类似问题的回答:***.com/a/65720209/4313735
【参考方案1】:
如果你想动态构建查询列表,你可以有一个这样的序列:
request = Q(name_contains='franz')
if condition1:
request |= Q(birthdate_date=date(2005, 5, 2))
if condition2:
request |= Q(param3_contains='lorem')
然后:
Students.objects.get(request)
如果你需要更通用的东西,你可以有一个传递字典的函数,比如:
conditions = 'name_contains': 'franz',
'birthdate_date': date(2005, 5, 2),
'param3_contains': 'lorem'
并像这样构建条件(未经测试):
request = None
for key, value in conditions.items():
new_request = Q(**key: value)
if request: request |= new_request
else: request = new_request
【讨论】:
是的,并且还需要在conditions
的末尾添加.items()
以避免too many values to unpack
异常。像这样。 for key, value in conditions.items():
【参考方案2】:
我的申请中有类似的要求。我必须搜索各种名称的搜索词:
Qterm = Q(firstname__icontains=searchterm) | \
Q(lastname__icontains=searchterm) | \
Q(resume__icontains=searchterm) | \
Q(companyname__icontains=searchterm))
或者,如果您想将一个字段与多个搜索词匹配:
Qterm = Q()
for term in ["robot", "animatronic", "automaton"]:
Qterm |= Q(rolename_icontains=term)
fieldname_icontains
最终变为LIKE
。还有更多的标准,比如用户应该是“活跃的”,这是一个布尔字段:
Qactive = Q(active=True)
最后,我像这样组合所有这些 Q 对象:
Qs = Qterm & Qactive & Qthis & Qthat
...然后我像这样检索我的活跃用户:
userlst = Users.objects.filter(Qs)
我希望这会有所帮助!
【讨论】:
我认为他希望查询集获取动态数量的参数,而不仅仅是一个searchterm
。
是的,你可能是对的。我将其添加到我的答案中。以上是关于如何为 django Q 对象动态加入多个参数的主要内容,如果未能解决你的问题,请参考以下文章