首页 > 解决方案 > 按两个值分组并获得第三个值

问题描述

我有这个带有三个 CharFields 的 Django 模型,我想对其运行查询以获取它们两个的现有值,并为每个组合获取第三个字段的现有值。

    a = models.CharField(null=False, max_length=8000)
    b = models.CharField(null=False, max_length=8000)
    c = models.CharField(null=False, max_length=8000)

如果假设这些值在数据库中:

 a  | b  | c  |
---------------
 a1 | b2 | c3 |
 a1 | b2 | c1 |
 a2 | b2 | c3 |
 a1 | b3 | c3 |
 a1 | b2 | c2 |

我想要这种形式的一些结果:

{"a1-b2" : [c3, c1, c2], "a2-b2" : [c3], "a1-b3" : [c3]}
or 
{"a1" : {"b2":[c3, c1, c2], "b3": [c3]}, "a2": {"b2" : [c3]}} 

标签: djangodjango-orm

解决方案


TLDR:

items = MyModel.objects.annotate(custom_field=Concat('a', Values('-'), 'b').values('custom_field', 'c')

解释

使用该部分.annotate(custom_field=Concat('a', Values('-'), 'b'),您基本上是在 SQL 中执行 group_by 操作,并在查询集中创建一个名为 name 的临时新列,custom_field其值为a-b.

这为您提供了以下结构:

a    |    b    |    c    | custom_field
a1        b1        c1          a1-b1
a2        b2        c2          a2-b2 
a1        b1        c3          a1-b1

.values('custom_field', 'c')部分仅从该查询集中获取custom_fieldc列。现在您所要做的就是序列化您的数据。

编辑 如果您希望数据采用该特定格式,您可以连接 column c。请阅读这篇文章中接受的答案。Django 按模型中的另一个字段创建一个字段分组列表。然后,您可以在序列化期间创建一个新字段,该字段会将split()连接的c字段放入列表中。


推荐阅读