【问题标题】:Queryset filter: retrieve manytomany field as list of each object查询集过滤器:检索多对多字段作为每个对象的列表
【发布时间】:2017-08-09 12:21:42
【问题描述】:

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

我的模型:

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


class Word(models.Model):
  word = models.CharField(max_length=256)

我有这个代码:

list(Wordlist.objects.all().annotate(w=F('words')).values_list('pk', 'w'))

它给了我这个:

[{'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}
 ...
]

我想要的是:

[{'pk': 1, 'w': [7, 13, 17, 42,...]},
 {'pk': 2, 'w': [29, 65,...]},
 {'pk': 3, 'w': [52,...]},
 ...
]

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

另外,我想知道是否可以用一个请求做相反的事情;在Word 上的请求中检索每个单词的Wordlist 列表。

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

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

    from django.contrib.postgres.aggregates.general import ArrayAgg
    
    Wordlist.objects.annotate(arr=ArrayAgg('words')).values_list('id', 'arr')
    

    【讨论】:

    • 我确实使用过 PostgresSQL,我以前从未遇到过,它真的很有用,谢谢。
    • 这是一个不错的解决方案
    • 有没有办法使用 MySQL 和 Django 3.x 实现相同的结果?
    猜你喜欢
    • 2013-08-18
    • 2020-06-16
    • 1970-01-01
    • 2016-12-13
    • 2021-07-07
    • 2018-01-03
    • 2022-12-21
    • 2016-10-27
    • 1970-01-01
    相关资源
    最近更新 更多