django-hordak icon indicating copy to clipboard operation
django-hordak copied to clipboard

Slow TransactionAdmin list view

Open PetrDlouhy opened this issue 3 years ago • 0 comments

The TransactionAdmin can be very slow due to vast number of DB queries. I tried to fix this with partial success - I reduced number of queries from ~900 to ~400 in my test case by this admin override:

@admin.register(models.Transaction)
class TransactionAdmin(hordak_admin.TransactionAdmin):
    def debited_accounts(self, obj):
        return ", ".join([str(leg.account) for leg in obj.debit_legs]) or None

    def total_amount(self, obj):
        return obj.total_amount

    def credited_accounts(self, obj):
        return ", ".join([str(leg.account) for leg in obj.credit_legs]) or None

    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).prefetch_related(
             Prefetch('legs', queryset=models.Leg.objects.filter(amount__gt=0).select_related("account"), to_attr="debit_legs"),
             Prefetch('legs', queryset=models.Leg.objects.filter(amount__lt=0).select_related("account"), to_attr="credit_legs"),
        ).annotate(
            total_amount=Sum("legs__amount", filter=Q(legs__amount__gt=0)),
        )

The code could be probably better implemented directly implemented in LegManager to make use of credits() and debits(), but anyway - I was not able to reduce number of queries to constant number and implement the prefetches in the manager.

PetrDlouhy avatar Sep 04 '20 10:09 PetrDlouhy