是否可以将传递的参数用作Django查询字符串中的值?
因此,让我们假设我想在term_list
,username
或display_name
等不同字段中搜索特定术语(在name
中)。
而不是多次这样做:
q1_username = Q(username__icontains=term_list[0])
q1_email = Q(email__icontains=term_list[0])
q2_username = Q(display_name__icontains=term_list[0])
q2_email = Q(e_mail__icontains=term_list[0])
q3_username = Q(name__icontains=term_list[0])
q3_email = Q(emailaddress__icontains=term_list[0])
我希望能够以更通用的方式针对不同情况进行此操作:
q1_username = "display_name"
q1_email = "emailaddress"
q1 = build_query(term_list, q1_username, q1_email)
def build_query(term_list, passed_username, passed_email):
q_username = Q(insert_passed_username_here__icontains=term_list[0])
q_email = Q(insert_passed_email_here__icontains=term_list[0])
# ...
return query
如果我这样尝试,我会收到以下错误消息,这并不奇怪:Cannot resolve keyword 'insert_passed_username_here' into field.
如何使用passed_username
和passed_email
替换函数中的insert_passed_username_here
和insert_passed_email_here
?
编辑: 根据@ Tsang-Yi Shen的回答,我更新了功能,但仍然出现错误。因此,让我们这样编辑我的问题,以使情况更清楚:
我在这样的不同数据库中有几个用户名和电子邮件:
"""query 1"""
q1_username = Q(username__icontains=term_list[0])
q1_email = Q(email__icontains=term_list[0])
special_q1 = q1_username | q1_email
for term in term_list[1:]:
special_q1.add((Q(username__icontains=term) | Q(email__icontains=term)), special_q1.connector)
"""query 2"""
q2_username = Q(name__icontains=term_list[0])
q2_email = Q(email__icontains=term_list[0])
special_q2 = crimenetwork_username | crimenetwork_email
for term in term_list[1:]:
special_q2.add((Q(name__icontains=term) | Q(email__icontains=term)), special_q2.connector)
构建此代码后,然后按如下所示过滤结果:
context = {}
context["q1_user_list"] = Users1.objects.using("db1").filter(special_q1)
context["q2_user_list"] = Users2.objects.using("db2").filter(special_q2)
问题:我大约有30个这样的查询,并且希望能够以更通用的方式实现。
如何像打开字典那样实现此目的?
答案 0 :(得分:3)
我经常先创建一个字典,然后解压缩它,例如:
def build_query(term_list, passed_username, passed_email):
q_username_dict = {passed_username + '__icontains': term_list[0]}
q_username = Q(**q_username_dict)
q_email_dict = {passed_email + '__icontains': term_list[0]}
q_email = Q(**q_email_dict)
尽管我仍在寻找更优雅的解决方案。
由于您最终将所有Q
放入了filter()
中,因此我建议创建一个Q
对象的列表:
def make_query(passed_username, passed_email, term_list):
return [
(Q(**{passed_username + '__icontains': term}) |
Q(**{passed_email + '__icontains': term})
for term in term_list
]
然后解压缩列表:
q_list = make_query('username', 'email', ['term01', 'term02'])
context["q1_user_list"] = Users1.objects.using("db1").filter(*q_list)
我也省去了.add()
和.connector
的使用,因为它应该等效于AND
之间的Q
操作。希望我不要误会你的意思