python - 在 django 的查询字符串中使用传递的参数作为值
问题描述
是否可以将传递的参数用作 django 查询字符串中的值?
所以,假设我想term_list
在不同的字段中搜索特定的术语 (in ),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
andpassed_email
替换函数中的insert_passed_username_here
and 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 个这样的查询,并且希望能够以更通用的方式进行。
我怎样才能通过像字典解包来实现这一点?
解决方案
我经常先创建一个字典,然后将其解包,例如:
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
s 放入 afilter()
中,因此我建议创建一个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)
我也消除了 and 的使用,.add()
因为.connector
它应该等同于sAND
之间的操作Q
。希望我没有误解你的意思
推荐阅读
- sql - JPA nullable=false 选项不会传播到 SQL 模式生成脚本
- python - 在 odeint Python 中使用 Dfun (Jacobian)
- r - 当将很棒的标记添加到传单时,R 闪亮的图标消失了
- c# - ASP.NET 身份多次登录
- scala - SBT 卡住下载工件
- java - JAVA XML:获取内容节点
- javascript - 如果输入文本值为空或 null,则删除元素
- python - 评估字符串的内容并匹配元组?
- python - 如何将文件从 docker 容器复制到 Jenkins
- jestjs - 无法使用 jest 测试从 node_modules 内部导入 SCSS 的 Svelte 组件