Django制作一个字段列表,按模型中的另一个字段分组

编程入门 行业动态 更新时间:2024-10-17 19:23:43
本文介绍了Django制作一个字段列表,按模型中的另一个字段分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个名为 MyModel 的模型,其中包含一些虚拟数据,如下所示:

项目日期值------------------------------ab 8/10/12 124ab 7/10/12 433ab 6/10/12 99美国广播公司 8/10/12 23美国广播公司 7/10/12 80

我想以得到如下输出的方式查询此模型:

[{'item': 'ab', 'values': [ 124, 433, 99]},{'item': 'abc', 'values': [ 23, 80]}]

我怎样才能使用 django ORM 做到这一点?

解决方案

(2016 年 4 月 4 日)更新:这是 Django <= 1.7 的有效解决方案.对于较新的版本,请阅读 创建您的自己的聚合函数来自文档.

使用取自 此处 的自定义 Concat 聚合(一篇关于该主题的文章)

定义:

class Concat(models.Aggregate):def add_to_query(self, query, alias, col, source, is_summary):#我们发送 source=CharField 以防止 Django 将字符串转换为 int聚合 = SQLConcat(col, source=models.CharField(), is_summary=is_summary, **self.extra)query.aggregates[别名] = 聚合#对于mysql类 SQLConcat(models.sql.aggregates.Aggregate):sql_function = 'group_concat'@财产def sql_template(self):如果 self.extra.get('separator'):return '%(function)s(%(field)s SEPARATOR "%(separator)s")'别的:返回 '​​%(function)s(%(field)s)'#对于 PostgreSQL >= 9.0#Aways 与分隔符一起使用,例如.annotate(values=Concat('value', separator=','))类 SQLConcat(models.sql.aggregates.Aggregate):sql_function = 'string_agg'@财产def sql_template(self):#the ::text cast 是一个硬编码的hack,用于处理整数列return "%(function)s(%(field)s::text, '%(separator)s')";#对于 PostgreSQL >= 8.4 和 <9.0#Aways 与分隔符一起使用,例如.annotate(values=Concat('value', separator=','))类 SQLConcat(models.sql.aggregates.Aggregate):sql_function = 'array_to_string'@财产def sql_template(self):return "%(function)s(array_agg(%(field)s), '%(separator)s')";#对于 PostgreSQL <8.4 你应该在使用之前定义array_agg:#CREATE AGGREGATE array_agg (anyelement)#(# sfunc = array_append,# stype = anyarray,# initcond = '{}'#);类 MyModel(models.Model):item = models.CharField(max_length = 255)日期 = 模型.DateTimeField()值 = 模型.IntegerField()

所以现在你可以这样做:

>>>从 my_app.models 导入 MyModel、Concat>>>MyModel.objects.values('item').annotate(values=Concat('value'))[{'item': u'ab', 'values': u'124,433,99'}, {'item': u'abc', 'values': u'23,80'}]

要获取values 作为整数列表,您需要手动.split 并转换为int.类似的东西:

>>>my_list = MyModel.objects.values('item').annotate(values=Concat('value'))>>>因为我在 my_list 中:... i['values'] = [int(v) for v in i['values'].split(',')]...>>>我的清单[{'item': u'ab', 'values': [124, 433, 99]}, {'item': u'abc', 'values': [23, 80]}]

I have a model called MyModel which has some dummy data as follows:

item date value ------------------------------ ab 8/10/12 124 ab 7/10/12 433 ab 6/10/12 99 abc 8/10/12 23 abc 7/10/12 80

I would like to query this Model in such a way that i get an output as follows:

[{'item': 'ab', 'values': [ 124, 433, 99]}, {'item': 'abc', 'values': [ 23, 80]}]

How would i be able to do this using the django ORM?

解决方案

(Apr 4 '16) UPDATE: This is a working solution for Django <= 1.7. For newer versions please read Creating your own Aggregate Functions from the docs.

Using a custom Concat aggregate taken from here (an article about the topic)

Define this:

class Concat(models.Aggregate): def add_to_query(self, query, alias, col, source, is_summary): #we send source=CharField to prevent Django from casting string to int aggregate = SQLConcat(col, source=models.CharField(), is_summary=is_summary, **self.extra) query.aggregates[alias] = aggregate #for mysql class SQLConcat(models.sql.aggregates.Aggregate): sql_function = 'group_concat' @property def sql_template(self): if self.extra.get('separator'): return '%(function)s(%(field)s SEPARATOR "%(separator)s")' else: return '%(function)s(%(field)s)' #For PostgreSQL >= 9.0 #Aways use with separator, e.g. .annotate(values=Concat('value', separator=',')) class SQLConcat(models.sql.aggregates.Aggregate): sql_function = 'string_agg' @property def sql_template(self): #the ::text cast is a hardcoded hack to work with integer columns return "%(function)s(%(field)s::text, '%(separator)s')" #For PostgreSQL >= 8.4 and < 9.0 #Aways use with separator, e.g. .annotate(values=Concat('value', separator=',')) class SQLConcat(models.sql.aggregates.Aggregate): sql_function = 'array_to_string' @property def sql_template(self): return "%(function)s(array_agg(%(field)s), '%(separator)s')" #For PostgreSQL < 8.4 you should define array_agg before using it: #CREATE AGGREGATE array_agg (anyelement) #( # sfunc = array_append, # stype = anyarray, # initcond = '{}' #); class MyModel(models.Model): item = models.CharField(max_length = 255) date = models.DateTimeField() value = models.IntegerField()

so now you can do:

>>> from my_app.models import MyModel, Concat >>> MyModel.objects.values('item').annotate(values=Concat('value')) [{'item': u'ab', 'values': u'124,433,99'}, {'item': u'abc', 'values': u'23,80'}]

to get values as a list of integers you need to manually .split and cast to int. Something like:

>>> my_list = MyModel.objects.values('item').annotate(values=Concat('value')) >>> for i in my_list: ... i['values'] = [int(v) for v in i['values'].split(',')] ... >>> my_list [{'item': u'ab', 'values': [124, 433, 99]}, {'item': u'abc', 'values': [23, 80]}]

更多推荐

Django制作一个字段列表,按模型中的另一个字段分组

本文发布于:2023-11-22 05:54:33,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1616218.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字段   模型   列表   Django

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!