在Django中使用Values从包含manymany字段的查询集中提取一个智能列表



我基本上有这个模型:

class MyModel(models.Model):
    uid = models.CharField()
    m2m = models.ManyToManyField(AnotherModel)
class AnotherModel(models.Model):
    name = models.CharField()
    lang = models.CharField()

,我想得到这样的字典列表(当然可能是过滤,但这很好):

[{
    'uid': uid,
    'm2m': [m2m.name, m2m.name, ...]
}]

如果我这样做:

MyModel.objects.select_related('m2m').filter().values('uid', 'm2m__name')

得到如下结果:

[{
    'uid': name_1,
    'm2m__name': m2m_1.name
},{
    'uid': name_1,
    'm2m__name': m2m_2.name
}]

我有两个问题:

  1. 我得到一个单独的列表项目 m2m!我只希望每个UID有一个,列表中有m2m个名字
  2. 我得到"m2m__name",我想只有"名称"或"m2m"

(如果我不明确地问m2m__name,只使用m2m,我不得到unicode,但ID)

有没有一种方法可以解决这些问题直接进入查询集而不经过python循环?最有效的方法是什么?

编辑

…也许使用.raw()或.extra()和一些自焙SQL至少可以解决问题2。

?
  • .raw ()
  • .extra ()

没有人对这个问题感兴趣,这听起来很奇怪,但我最终对结果进行了循环,以构建我自己想要的列表:

my_list = {}
for item in items:
    _uid = item['uid']
    _name = item['m2m__name']
    list_item = my_list.get(, {'uid': _uid, 'name': set([_name])})
    list_item['name'].add(_name)

这将产生如下内容:

my_list = { 'uid': {
    'uid': uid,
    'm2m': [m2m.name, m2m.name, ...]
}}

哪些项目正是问题中所要求的。

我希望能够在QuerySet级别解决至少一个问题…

我自己也有这个问题,我必须把多个信息拼凑在一起才能得到我的答案。对于其他人,这是我的发现。这只适用于Postgres>= 9.4Django>= 9.0

你可以这样做:

MyModel.objects.filter( ... ).values('uid', names=ArrayAgg('m2m__name'))

将产生以下内容:

<MyModelQuerySet [{'uid': 'id_1', 'names': ['name_1', 'name_2', ...]}]>

最新更新