Django, как создать поле ForeignKey при .annotate?

Я хотел создать поле ForeignKey в Django с помощью .annotate, но не смог найти ни одной опции для этого, возможно, ее не существует. Я просто хочу LEFT JOIN определенной модели с определенным условием. Но сейчас я должен сделать это следующим образом:

queyrset = Invoice.objects.annotate(provided_amount=Subquery(InvoicePayment.objects.filter(invoice_id=OuterRef("id"), date=timezone.now().date()).values("provided_amount")))

queryset.first().provided_amount

Но я хочу вот так:

queryset = Invoice.objects.annotate(invoice_payment=...)

queryset.first().invoice_payment.provided_amount

Я мог бы сделать это с помощью свойств, но я не хочу делать это таким образом, я хотел бы сделать все в одном запросе.

Может быть, существует библиотека для этого?

Django - 4.2.4 Python - 3.10

Я пробовал создать SQL VIEW и привязать его к модели с помощью managed = False, но это не очень удобно делать каждый раз.

Пожалуйста, не используйте related_name='+': это означает, что делать обратные запросы теперь гораздо сложнее. Вместо этого мы можем назвать отношение payments:

class InvoicePayment(models.Model):
    invoice = models.ForeignKey(
        Invoice, on_delete=models.CASCADE, related_name='payments'
    )
    date = models.DateField()
    provided_amount = models.DecimalField(
        max_digits=64, decimal_places=24, null=True
    )

    class Meta:
        unique_together = ['invoice', 'date']


class Invoice(models.Model):
    pass

Тогда мы можем работать с FilteredRelation [Django-doc]:

from django.db.models import FilteredRelation, Q

qs = Invoice.objects.annotate(
    todays_payment=FilteredRelation(
        'payments', condition=Q(payments__date=timezone.now().date())
    ),
).select_related('todays_payment')

и, например,

qs.first().todays_payment.provided_amount
Вернуться на верх