Django Count and Sum annotations interfere with each other

前端 未结 3 525
面向向阳花
面向向阳花 2020-12-09 12:06

While constructing a complexe QuerySet with several annotations, I ran into an issue that I could reproduce with the following simple setup.

Here are th

3条回答
  •  时光说笑
    2020-12-09 12:07

    Based on the excellent answer from @rktavi, I created two helpers classes that simplify the Subquery/Count and Subquery/Sum patterns:

    class SubqueryCount(Subquery):
        template = "(SELECT count(*) FROM (%(subquery)s) _count)"
        output_field = PositiveIntegerField()
    
    
    class SubquerySum(Subquery):
        template = '(SELECT sum(_sum."%(column)s") FROM (%(subquery)s) _sum)'
    
        def __init__(self, queryset, column, output_field=None, **extra):
            if output_field is None:
                output_field = queryset.model._meta.get_field(column)
            super().__init__(queryset, output_field, column=column, **extra)
    

    One can use these helpers like so:

    from django.db.models import OuterRef
    
    weapons = Weapon.objects.filter(unit__player_id=OuterRef('id'))
    units = Unit.objects.filter(player_id=OuterRef('id'))
    
    qs = Player.objects.annotate(weapon_count=SubqueryCount(weapons),
                                 rarity_sum=SubquerySum(units, 'rarity'))
    

提交回复
热议问题