How to sum a field of a subquery ( with OuterRef ) and annotate it on outer model?
note that I have a common my_special_queryset_annotator
that alter queryset by adding some annotations, ... so i dont want to use direct Sum('books__sections__page')
let assume following models
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')
)
)
)
one try that solve the problem in ugly way is to create something like below, but i cant configure how not to pass sum_field
parameter to it and just use .values(sum_field)
on given queryset
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',
)
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.