簡體   English   中英

Django注釋總和子查詢

[英]Django annotate sum subquery

如何對子查詢的字段求和(使用OuterRef)並在外部模型上對其進行注釋?

請注意,我有一個常見的my_special_queryset_annotator通過添加一些注釋來更改查詢集,...所以我不想使用直接Sum('books__sections__page')

讓我們假設以下模型

class Library(models.Model):
    votes=models.IntegerField()

class Book(models.Model):
    library=models.ForiegnKey(Library)

class Section(models.Model):
    book=models.ForiegnKey(Book)
    pages=models.IntegerField()

# this works, but when want to use `my_special_queryset_annotator` 
# we could not do this simple annotation
Library.annotate(
    all_pages=Sum('books__sections__pages'),
)

# when want to sum on a Subquery, its must constructed like below but it dont work
Library.objects.annotate(
    all_pages=SUM(  # <-- problem
        Subquery(
            my_special_queryset_annotator(
                Section.objects.filter(book__libraray_id=OuterRef('id'))
            ).values('altered_pages')
        )
    )
)

解決丑陋問題的一種方法是創建如下所示的內容,但是我無法配置如何不將sum_field參數傳遞給它,而僅在給定queryset上使用.values(sum_field)

class SumSubquery(Subquery):
    template = "(SELECT SUM(%(sum_field)s) FROM (%(subquery)s) _sum)"
    output_field = models.DecimalField()

    def __init__(self, queryset, output_field=None, *, sum_field, **extra):
        extra['sum_field'] = sum_field
        super(SumSubquery, self).__init__(queryset, output_field, **extra)
# and use like below

Library.objects.annotate(
    all_pages=SumSubquery(
        my_special_queryset_annotator(
            Section.objects.filter(book__libraray_id=OuterRef('id'))
        ),
        sum_field='altered_pages',
    )
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM