fix(views): optimize database queries to solve N+1 problems 🔨🐛

This commit is contained in:
2025-07-25 23:22:35 +05:00
parent 118ad52c71
commit 4aae0064ca
5 changed files with 39 additions and 29 deletions

View File

@@ -13,6 +13,7 @@ from rest_framework.response import Response
from api.mixins import StaffEditorPermissionMixin
from api.tasks import add_new_devices_to_omada
from apibase.env import BASE_DIR, env
from django.db.models import Prefetch
import logging
from .models import Device, Payment, Topup, WalletTransaction
@@ -60,10 +61,18 @@ class ListCreatePaymentView(StaffEditorPermissionMixin, generics.ListCreateAPIVi
filterset_class = PaymentFilter
def get_queryset(self):
queryset = super().get_queryset()
if self.request.user.is_superuser:
return queryset
return queryset.filter(user=self.request.user)
unpaid_qs = Payment.objects.filter(paid=False).order_by("-created_at")
device_qs = Device.objects.prefetch_related(
Prefetch("payments", queryset=unpaid_qs, to_attr="unpaid_payments")
)
queryset = Payment.objects.select_related("user").prefetch_related(
Prefetch("devices", queryset=device_qs)
)
if not self.request.user.is_superuser:
queryset = queryset.filter(user=self.request.user)
return queryset
def create(self, request):
data = request.data
@@ -163,7 +172,7 @@ class UpdatePaymentAPIView(StaffEditorPermissionMixin, generics.UpdateAPIView):
class VerifyPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView):
serializer_class = PaymentSerializer
queryset = Payment.objects.all()
queryset = Payment.objects.select_related("user").all()
lookup_field = "pk"
def update(self, request, *args, **kwargs):
@@ -322,7 +331,7 @@ class VerifyPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView):
class CancelPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView):
queryset = Payment.objects.all()
queryset = Payment.objects.select_related("user").all()
serializer_class = PaymentSerializer
lookup_field = "pk"
@@ -352,7 +361,7 @@ class CancelPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView):
class ListCreateTopupView(StaffEditorPermissionMixin, generics.ListCreateAPIView):
queryset = Topup.objects.all()
queryset = Topup.objects.all().prefetch_related("user")
serializer_class = TopupSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields = "__all__"