查询集过滤器:检索 manytomany 字段作为每个对象的列表

Qro*_*rom 5 python django django-queryset

我想检索模型的每个对象,仅包含它们的 id 和它们在多对多字段中的 id 列表。

我的模型:

class Wordlist(models.Model):
  words = models.ManyToManyField(Word)


class Word(models.Model):
  word = models.CharField(max_length=256)
Run Code Online (Sandbox Code Playgroud)

我有这个代码:

list(Wordlist.objects.all().annotate(w=F('words')).values_list('pk', 'w'))
Run Code Online (Sandbox Code Playgroud)

它给了我这个:

[{'pk': 1, 'w': 7},
 {'pk': 1, 'w': 13},
 {'pk': 1, 'w': 17},
 {'pk': 2, 'w': 29},
 {'pk': 1, 'w': 42},
 {'pk': 3, 'w': 52},
 {'pk': 2, 'w': 65}
 ...
]
Run Code Online (Sandbox Code Playgroud)

我想要的是:

[{'pk': 1, 'w': [7, 13, 17, 42,...]},
 {'pk': 2, 'w': [29, 65,...]},
 {'pk': 3, 'w': [52,...]},
 ...
]
Run Code Online (Sandbox Code Playgroud)

一个简单的解决方案是根据它们的 id 组合 dicts,但我认为这不是一个好的做法并且非常有效,因为结果我们可能有数十万个 dicts。

另外,我想知道是否可以通过一个请求来做相反的事情;检索一个Wordlist词的列表是针对请求中的每个词Word

Dim*_*osh 10

如果您使用 PostgreSQL,您可以使用在django.contrib.postgres包中实现的 array_agg 函数。您的查询将如下所示:

from django.contrib.postgres.aggregates.general import ArrayAgg

Wordlist.objects.annotate(arr=ArrayAgg('words')).values_list('id', 'arr')
Run Code Online (Sandbox Code Playgroud)