mysql - 使用 Django 将查询集中的查询分组为一个查询

标签 mysql django python-3.x orm django-queryset

我有一个如下所示的查询集。

<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)  

请提供一种方法,以便可以根据“用户”将两个查询合并为一个查询,并且在合并后“移动”应该包含两个值。

编辑:我将通过正在绘制表格的 View 将此查询集传递给模板。目前,对于每个查询,一行是 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 key 是一个字典,其中包含用于在表中显示的键。示例:

Required_keys = {
    'User Name':user,
    'Contact':mobile,
    'Address':home,
} 

get item是一个函数,它在传递key时获取值。

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

函数的值参数是整个查询集。但是这个功能 如上所述,如果查询集中只有一个用户,则有效。但如果有 是多个用户,它失败了。

编辑 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)

关于mysql - 使用 Django 将查询集中的查询分组为一个查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52205994/

相关文章:

php - 关于 MySQL JOIN 的建议

C# 和 MySql,在两个日期之间选择

c# - 如何确定是否在 MySql 连接中使用 SSL?

python - 同一页面上的重复占位符

python-3.x - 将数组行 append 到 Python 3 中的 .txt 文件

c# - MySQL 在字符串前面添加空格

python - MySQL 准备好的语句在 Django 中产生错误,但在命令行中有效

python - 在 Django 中,如何使用请求来确定其 URLconf View 名称?

python-3.x - 如何根据 tkinter 列表框中已打乱项目的索引设置选择栏

python - 如何修复 Windows 10 中的 'Pyautogui.mouseUP' 和 mouseDown 问题