Combine prefetch_related and annotate in Django

*爱你&永不变心* 提交于 2019-12-10 16:27:40

问题


I have three models

class ModelA(models.Model):
    name = CharField(max_length=100)

class ModelB(models.Model):
    modela = ForeignKey(ModelA)

class ModelC(models.Model):
    modelb = ForeignKey(ModelB)
    amount = IntegerField()

I can get the output

name, number of model c objects
==============
Some name, 312
Another name, 17

With the queryset

ModelA.objects.all().prefetch_related('modelb_set', 'groupb_set__modelc_set')

and template

{% for modela in modela_list %}
    {% for modelb in modela.modelb_set.all %}
        {{ modelb }}, {{ modelb.modelc_set.count }}
    {% endfor %}
{% endfor %}

Instead of counting the number of ModelC objects connected to each ModelB object I want to sum the amount field in ModelC.

I don't know how to combine prefetch_related and annotate in my queryset, but it must be something like

ModelA.objects.all().prefetch_related('modelb_set', 'groupb_set__modelc_set').annotate(total_amount=Sum('modelc_set__amount'))

回答1:


I think you should be able to achieve that by doing this:

from django.db.models import F, Sum

ModelA.objects.all()\
    .prefetch_related('modelb_set', 'modelb__modelc_set')\
    .values('name')\ # group values by modela.name, read: https://docs.djangoproject.com/en/1.9/topics/db/aggregation/
    .annotate(name = F('name'),
              total_amount = Sum('modelb__modelc__amount'))

and in your template you should use:

{% for modela in modela_list %}
    {{ modela.name }}, {{ modela.total_amount }}
{% endfor %}


来源:https://stackoverflow.com/questions/25386272/combine-prefetch-related-and-annotate-in-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!