Django 多对多计数和优化查询
我有一个Django 多对多计数和优化查询,django,python-3.x,Django,Python 3.x,我有一个Word模型 它有一个多对多字段 短语型号 我用json格式将我的话传给前端,如下所示: words_json = [] words = Word.objects.filter(....filter_by_some_params) for word in words: single_word_json = {} single_word_json['id'] = word.id single_word_json['name'] = word.
Word
模型
它有一个多对多字段
短语
型号
我用json
格式将我的话传给前端,如下所示:
words_json = []
words = Word.objects.filter(....filter_by_some_params)
for word in words:
single_word_json = {}
single_word_json['id'] = word.id
single_word_json['name'] = word.name
single_word_json['count'] = len(word.phrases.all())
words_json.appen(word_json)
return words_json
我觉得这样做没有效果,也无法扩展(我会有多达10000个单词和短语,那么我该怎么办?您可以使用以下方法:
from django.db.models import Count
qs = Word.objects.filter(..).annotate(
count=Count('phrase')
).values('id', 'name', 'count')
那么你的words\u json
就是:
words_json = list(qs)
.values()
将构建一个字典查询集。每个字典将包含三项:id
、name
和count
。count
源于.annotate(…)
函数,我们在其中计算短语的数量
这样做的好处是,我们将在一个查询中完成所有处理,如:
选择w.id、w.name、COUNT(wp.phrase\u id)
从单词w开始
在w.id=wp.word\u id上作为wp的左外连接词\u短语
按w.id、w.name分组
因此,我们不执行n+1查询(n是.filter(..)
中的单词数),而是执行单个查询。此外,我们限制数据库返回结果所需的带宽,并让Django为我们将响应包装到字典中
编辑:如果一个单词
有一个外键
指向一个组
,并且您还想包含名称,您可以这样写:
from django.db.models import Count, F
qs = Word.objects.filter(..).annotate(
count=Count('phrase'),
group_name=F('group__name')
).values('id', 'name', 'count', 'group_name')
从django.db.models导入计数,F
qs=Word.objects.filter(..).annotate(
count=count('短语'),
组名称=F('组名称')
).values('id','name','count','group\u name')
现在,每个字典都会有一个额外的键组名
。如果单词
没有组名
,那么组名
将是无
(或者在JSON中为空
).还有一个问题:如果每个单词都有一个到组的外键
模型,我如何才能传递到我的结果列表'Group.name
?那么你想在JSON blob中包含组名?然后你可以执行额外的注释,例如组名=F('Group\u name'))
并将其包含在值中。好的,还有最后一个问题:如果我需要向生成的对象传递一个空数组-如何使用annotate:single_word_json['connected_words_to_check']=[]
@user2950593:不,那么您必须手动修补每个字典。但是这通常会很快,因为不涉及任何查询。如果可能的话,在查询集中注释常量实际上会比较慢。如果出现错误怎么办:注释组
与字段组冲突。我可以做些什么吗是否在不重命名结果字段的情况下使用此选项?