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

@@ -36,9 +36,9 @@ class DeviceSerializer(serializers.ModelSerializer):
def get_pending_payment_id(self, obj):
unpaid_payment = (
Payment.objects.filter(devices=obj, paid=False)
.order_by("-created_at")
.first()
obj.unpaid_payments[0]
if hasattr(obj, "unpaid_payments") and obj.unpaid_payments
else None
)
return unpaid_payment.id if unpaid_payment else None
@@ -63,9 +63,9 @@ class AdminDeviceSerializer(serializers.ModelSerializer):
def get_pending_payment_id(self, obj):
unpaid_payment = (
Payment.objects.filter(devices=obj, paid=False)
.order_by("-created_at")
.first()
obj.unpaid_payments[0]
if hasattr(obj, "unpaid_payments") and obj.unpaid_payments
else None
)
return unpaid_payment.id if unpaid_payment else None

View File

@@ -3,7 +3,9 @@ from xmlrpc.client import Boolean
from rest_framework import generics, status
from rest_framework.response import Response
from django_filters.rest_framework import DjangoFilterBackend
from billing.models import Payment
from .models import Device
from django.db.models import Prefetch
from .serializers import (
CreateDeviceSerializer,
DeviceSerializer,
@@ -28,6 +30,13 @@ class DeviceListCreateAPIView(
filterset_fields = "__all__"
filterset_class = DeviceFilter
def get_queryset(self):
unpaid_qs = Payment.objects.filter(paid=False).order_by("-created_at")
base_qs = Device.objects.select_related("user").prefetch_related(
Prefetch("payments", queryset=unpaid_qs, to_attr="unpaid_payments")
)
return base_qs.all()
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
all_devices = request.query_params.get("all_devices", "false").lower() in [
@@ -90,7 +99,7 @@ class DeviceDetailAPIView(StaffEditorPermissionMixin, generics.RetrieveAPIView):
class DeviceUpdateAPIView(StaffEditorPermissionMixin, generics.UpdateAPIView):
queryset = Device.objects.all()
queryset = Device.objects.select_related("user").all()
serializer_class = CreateDeviceSerializer
lookup_field = "pk"
@@ -116,7 +125,7 @@ class DeviceUpdateAPIView(StaffEditorPermissionMixin, generics.UpdateAPIView):
class DeviceBlockAPIView(StaffEditorPermissionMixin, generics.UpdateAPIView):
queryset = Device.objects.all()
queryset = Device.objects.select_related("user").all()
serializer_class = BlockDeviceSerializer
lookup_field = "pk"
@@ -154,7 +163,7 @@ class DeviceBlockAPIView(StaffEditorPermissionMixin, generics.UpdateAPIView):
class DeviceDestroyAPIView(StaffEditorPermissionMixin, generics.DestroyAPIView):
queryset = Device.objects.all()
queryset = Device.objects.select_related("user").all()
serializer_class = DeviceSerializer
lookup_field = "pk"