diff --git a/dref/serializers.py b/dref/serializers.py index f3801fa33..98bc391e8 100644 --- a/dref/serializers.py +++ b/dref/serializers.py @@ -252,24 +252,41 @@ class Meta: @extend_schema_field(MiniOperationalUpdateActiveSerializer(many=True)) def get_operational_update_details(self, obj): - queryset = DrefOperationalUpdate.objects.filter(dref_id=obj.id).order_by("-created_at") + prefetched = getattr(obj, "prefetched_operational_updates", None) + queryset = prefetched if prefetched is not None else obj.drefoperationalupdate_set.order_by("-created_at") return MiniOperationalUpdateActiveSerializer(queryset, many=True).data @extend_schema_field(MiniDrefFinalReportActiveSerializer) def get_final_report_details(self, obj): - queryset = DrefFinalReport.objects.filter(dref_id=obj.id).first() - return MiniDrefFinalReportActiveSerializer(queryset).data + prefetched = getattr(obj, "prefetched_final_report", None) + if prefetched is not None: + if isinstance(prefetched, list): + final_report = prefetched[0] if prefetched else None + else: + final_report = prefetched + else: + try: + final_report = obj.dreffinalreport + except DrefFinalReport.DoesNotExist: + final_report = None + if final_report is None: + return None + return MiniDrefFinalReportActiveSerializer(final_report).data def get_has_ops_update(self, obj) -> bool: - op_count_count = obj.drefoperationalupdate_set.count() - if op_count_count > 0: - return True - return False + prefetched = getattr(obj, "prefetched_operational_updates", None) + if prefetched is not None: + return len(prefetched) > 0 + return obj.drefoperationalupdate_set.exists() def get_has_final_report(self, obj) -> bool: - if hasattr(obj, "dreffinalreport"): - return True - return False + prefetched = getattr(obj, "prefetched_final_report", None) + if prefetched is not None: + return bool(prefetched) + try: + return obj.dreffinalreport is not None + except DrefFinalReport.DoesNotExist: + return False def get_application_type(self, obj) -> str: return "DREF" @@ -278,10 +295,28 @@ def get_application_type_display(self, obj) -> str: return gettext("DREF application") def get_unpublished_op_update_count(self, obj) -> int: + prefetched = getattr(obj, "prefetched_operational_updates", None) + if prefetched is not None: + return sum(1 for op in prefetched if op.status != Dref.Status.APPROVED) return DrefOperationalUpdate.objects.filter(dref_id=obj.id).exclude(status=Dref.Status.APPROVED).count() def get_unpublished_final_report_count(self, obj) -> int: - return DrefFinalReport.objects.filter(dref_id=obj.id).exclude(status=Dref.Status.APPROVED).count() + prefetched = getattr(obj, "prefetched_final_report", None) + if prefetched is not None: + if isinstance(prefetched, list): + if not prefetched: + return 0 + final_report = prefetched[0] + else: + final_report = prefetched + if final_report is None: + return 0 + return 0 if final_report.status == Dref.Status.APPROVED else 1 + try: + final_report = obj.dreffinalreport + except DrefFinalReport.DoesNotExist: + return 0 + return 0 if final_report.status == Dref.Status.APPROVED else 1 class PlannedInterventionSerializer( diff --git a/dref/views.py b/dref/views.py index 3f1ee97fc..4c8ff2d01 100644 --- a/dref/views.py +++ b/dref/views.py @@ -5,6 +5,7 @@ import django.utils.timezone as timezone from django.contrib.auth.models import Permission from django.db import models, transaction +from django.db.models import Prefetch from django.http import HttpResponse from django.templatetags.static import static from django.utils.translation import gettext @@ -345,7 +346,23 @@ class ActiveDrefOperationsViewSet(viewsets.ReadOnlyModelViewSet): permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] filterset_class = ActiveDrefFilterSet queryset = ( - Dref.objects.prefetch_related("planned_interventions", "needs_identified", "national_society_actions", "users") + Dref.objects.select_related("country") + .prefetch_related( + "planned_interventions", + "needs_identified", + "national_society_actions", + "users", + Prefetch( + "dreffinalreport", + queryset=DrefFinalReport.objects.all(), + to_attr="prefetched_final_report", + ), + Prefetch( + "drefoperationalupdate_set", + queryset=DrefOperationalUpdate.objects.order_by("-created_at"), + to_attr="prefetched_operational_updates", + ), + ) .order_by("-created_at") .filter(is_active=True) .distinct()