Django ORM дублирует LEFT OUTER JOIN в SQL при аннотировании

Проблема

Когда я добавляю аннотацию на основе обратного поля, то в результате SQL появляется двойной "LEFT OUTER JOIN". В результате аннотация суммы считается неправильной (дублируется в зависимости от количества обратных аннотаций)

Как сделать аннотацию суммы правильной?

Django 4.0.3
Python 3.10

Result SQL

SELECT 
  "frontend_book"."id", 
  "frontend_book"."title", 
  "frontend_book"."author_id", 
  COALESCE(
    SUM("frontend_sell"."price"), 
    0
  ) AS "total_profit_author", 
  COALESCE(
    SUM(T4."price"), 
    0
  ) AS "total_profit_resolver" 
FROM 
  "frontend_book" 
  INNER JOIN "frontend_human" ON (
    "frontend_book"."author_id" = "frontend_human"."id"
  ) 
  LEFT OUTER JOIN "frontend_sell" ON (
    "frontend_human"."id" = "frontend_sell"."author_id"
  ) 
  LEFT OUTER JOIN "frontend_sell" T4 ON ( <----- HERE
    "frontend_human"."id" = T4."resolver_id"
  ) 
GROUP BY 
  "frontend_book"."id"

Модели

class Human(models.Model):
    name = models.CharField(
        'Name',
        max_length=200,
        blank=True,
    )

class Book(models.Model):
    title = models.CharField(
        'Title',
        max_length=200,
        blank=True,
    )

    author = models.ForeignKey(
        Human,
        verbose_name='author',
        related_name='books',
        on_delete=models.CASCADE,
    )

class Sell(models.Model):
    author = models.ForeignKey(
        Human,
        verbose_name='Author',
        related_name='author_sells',
        on_delete=models.CASCADE,
    )

    resolver = models.ForeignKey(
        Human,
        verbose_name='Resolver',
        related_name='resolver_sells',
        on_delete=models.CASCADE,
    )

    price = models.FloatField(
        'Price',
        default=0,
        blank=True
    )

Виды

from rest_framework.response import Response
from rest_framework.views import APIView
from backend.api.frontend.models import Book
from django.db.models import Sum, FloatField


from .serializers import BookSerializer

class TestView(APIView):
    def get(self, request):

        qs = Book.objects.all()

        qs = qs.annotate(
            total_profit_author = Sum(
                'author__author_sells__price',
                output_field=FloatField(),
                default=0,
            ),
            total_profit_resolver = Sum(
                'author__resolver_sells__price',
                output_field=FloatField(),
                default=0,
            ),
        )


        return Response({
            "data": BookSerializer(qs, many=True).data,
        })

Serializers

from rest_framework import serializers
from .models import Book


class BookSerializer(serializers.Serializer):
    total_profit_author = serializers.FloatField(read_only=True)
    total_profit_resolver = serializers.FloatField(read_only=True)

    class Meta:
        model = Book
        fields = '__all__'

Отличный ответ https://stackoverflow.com/a/56619484/9477837

Django ORM problem (13 years old) https://code.djangoproject.com/ticket/10060

Вернуться на верх