mysql - 使用 Django 将查询集中的查询组合成一个查询
问题描述
我有一个如下所示的查询集。
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234},
{'user':'xyz','id':12,'home':'qwe','mobile':4321},
{'user':'abc','id':13,'home':'def','mobile':1233},
{'user':'abc','id':13,'home':'def','mobile':1555},]>
这个 QuerySet 由 django 返回,使用
users.objects.all()
对于查询集中的每个查询,我在前端绘制了一个用户表,其中显示了用户的详细信息。如果同一个“用户”注册了两个“手机”号码,则在表格中显示为两行而不是一行。我的目标是在同一行中显示两个数字,而不是创建两行。
我想到了以下两种可能的解决方案:
解决方案 1:如果两个查询中的“用户”值匹配,我曾考虑将两个查询合并为一个。为此,我们需要使用条件语句进行大量检查,当有很多用户时,条件语句运行缓慢。
解决方案 2:我在 Google 上搜索并提出了 Group By Django,但它不起作用。我在下面尝试过
query = users.objects.all().query
query.group_by = ['mobile']
results = QuerySet(query=query, model=users)
请提供一种方法,以便可以基于“用户”将两个查询合并为一个,并且在合并后“移动”应包含两个值。
编辑:我将通过正在绘制表格的视图将此查询集传递给模板。目前,对于每个查询,一行是 in 表。由于上述查询集有四个查询,我们将有四行。但我只想在两行中显示信息,因为“id”和“user”是相同的。模板代码如下:
{% if users %}
{% for user in users %}
{% for k,v in required_keys.items %}
<td>{{ user | get_item:k }}
{% endfor %}
{% endfor %}
{% endif %}
必需键是一个字典,其中包含用于在表中显示的键。例子:
Required_keys = {
'User Name':user,
'Contact':mobile,
'Address':home,
}
get item 是一个函数,它在传递 key 时获取 value。
def get_item(dictionery,key):
return dictionery.get(key)
编辑2:我已经尝试过解决方案,它不是一个完整的解决方案,但它部分解决了问题。该解决方案完美适用于一位用户。但是,如果有很多用户,则该解决方案不起作用。请参见下面的示例:
# input query set to the function which partially solves the problem
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234},
{'user':'xyz','id':12,'home':'qwe','mobile':4321},]>
# Now our team has written a function which gives the following output
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234,4321},]>
但是如果有多个用户,则输出与输入相同,它不会包含查询。请看下面的函数:
def merge_values(cls,values):
import itertools
grouped_results = itertools.groupby(values,key=lambda x:x['id'])
merged_values = []
for k,g in grouped_results:
groups=list(g)
merged_value = {}
for group in groups:
for key, val in group.iteritems():
if not merged_value.get(key):
merged_value[key] = val
elif val != merged_value[key]:
if isinstance(merged_value[key], list):
if val not in merged_value[key]:
merged_value[key].append(val)
else:
old_val = merged_value[key]
merged_value[key] = [old_value, val]
merged_values.append(merged_value)
return merged_values
该函数的 values 参数是整个查询集。但是如果如上所述查询集中只有一个用户,则此功能有效。但是如果有多个用户,它就会失败。
编辑3:我发现为什么上述功能不适用于多个用户(不知道这是否正确)。为函数设置的输入查询(对于一个用户)是
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234},
{'user':'xyz','id':12,'home':'qwe','mobile':4321},]>
由于两个用户查询是一个接一个的,因此它们被合并了。但是如果有多个用户,传递给函数的查询集是
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234},
{'user':'xyz','id':13,'home':'qwe','mobile':4321},
{'user':'abc','id':12,'home':'def','mobile':1233},
{'user':'abc','id':13,'home':'def','mobile':1555},]>
在上述查询集中,具有相同 id 的用户不是一个接一个,因此该函数无法获得所需的输出。
解决方案
您可以使用您编写的函数,只需要更改是需要根据 id 对值进行排序。因此,在从对象中获取值之前,order_by('id')
请获取所需的值并将其传递给您的函数以合并值。
例如。
query_set = Mymodel.objects.filter(name='Required').order_by('id')
values = query_set.values('id', 'field1', 'field2')
merged_values = merge_values(values)
推荐阅读
- javascript - 如何使用 DataTables (serverSide: true) 实现单个列过滤器?
- c - 想知道在将数组旋转 2 个位置时我哪里出错了(大小 = n = 7,距离 = d = 2)
- c# - AWS .NET SDK 使用 ASP.NET Core 依赖注入配置 S3 客户端
- javascript - 在 Polymer 2 中无法通过 id 获取元素
- python - Python Flask 调用不同版本的 API
- android - Jsoup Doc.select() 返回 null
- java - 如何捕获一个空数组[0](异常)
- c# - Windbg 查看堆栈内容
- swift - 如何在 TextField (SwiftUI) 上添加底线
- python - 是否可以在不和谐机器人中具有耳语功能?