How to prefetch aggregated @property in Django?

后端 未结 1 1158
死守一世寂寞
死守一世寂寞 2020-12-30 13:45

We have two models (simplified versions):

class Contestant(models.Model):
    email = models.EmailField(max_length=255, unique=True)
    # plus some other fi         


        
相关标签:
1条回答
  • 2020-12-30 14:12

    When your aim is to add aggregated values to each item, you should use annotate, instead of aggregate.

    For example (a simple query, no additional methods required):

    Contestant.objects.filter(...).annotate(total_points=Sum('points__value'))
    

    If you really want to put this code out of your query: you can, but a model method is not a right way to do this. Methods on models are for operations on single instances. If you want to do something on a whole QuerySet use an ORM Manager instead.

    With a Manager this would look like this:

    class TotalPointsManager(models.Manager):
        def get_queryset(self):
            return super(TotalPointsManager, self).get_queryset().annotate(total_points=Sum('points__value'))
    
    class Contestant(models.Model):
        email = models.EmailField(max_length=255, unique=True)
    
        objects = TotalPointsManager() # You are overriding the default manager!
    

    and then you would construct your query as usual (you can drop prefetch_related):

    Contestant.objects.filter(...)
    

    ...and total_points field would become "magically" available for every object.

    0 讨论(0)
提交回复
热议问题