我有一个类似下面的查询集。
<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},]>
django使用
返回此QuerySet。users.objects.all()
对于查询集中的每个查询,我正在前端绘制一个用户表,其中显示了用户的详细信息。如果相同的“用户”注册了两个“手机”号码,则在表中显示为两行而不是一行。我的目标是在同一行中显示两个数字,而不是创建两行。
我想到了以下两种可能的解决方案:
解决方案1:如果两个查询中的'user'值都匹配,我曾考虑将两个查询合并为一个。为此,我们需要使用条件语句进行大量检查,条件语句在有大量用户时运行缓慢。
解决方案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,
}
获取项是一个函数,该函数在传递键时获取值。
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的用户不是一个接一个的,因此该函数无法获得所需的输出。
答案 0 :(得分:1)
您可以使用已编写的函数,只需更改即可,只需根据ID排序值即可。
因此,在从对象"ABC"
"\u0017"
"world"
"\u000B"
"Mama"
"\u000B"
"Gerama"
"\u000B"
获取值之前,请获取所需的值并将其传递给函数以合并值。
例如。
order_by('id')
答案 1 :(得分:0)
首先,将有助于更好地组织模型。您的user
模型中有重复的用户信息。如果您知道某个用户拥有多个手机号码,则最好为此创建一个单独的模型:
class Mobile(models.Model)
number = models.IntegerField()
user = models.ForeignKey(User)
然后,当您进行查询并想要获取所有手机号码时,首先需要在视图中使用users = User.objects.all()
,然后在模板中使用所有用户:
{% for user in users %}
{% for mobile in user.mobile_set.all %}
<td>{{ user }}</td>
<td>{{ mobile.number }}</td>
{% endfor %}
{% endfor %}
作为旁注,我认为将您的模型命名为单数(User
而不是Users
)是一种更好的做法