Parcourir la source

optimisation de la liste des antennes

Élie Bouttier il y a 7 ans
Parent
commit
7eb6961967
1 fichiers modifiés avec 29 ajouts et 2 suppressions
  1. 29 2
      services/admin.py

+ 29 - 2
services/admin.py

@@ -11,7 +11,11 @@ from django.conf.urls import url
 from django.template.response import TemplateResponse
 from django.core.serializers import serialize
 from django.http import HttpResponse
+from django.db.models.functions import Cast
+from django.contrib.postgres.aggregates import StringAgg
+from django.db import connection
 
+from djadhere.utils import get_active_filter
 from adhesions.models import Adhesion
 from .models import Service, ServiceType, IPPrefix, IPResource, Route, Tunnel, ServiceAllocation, Antenna, AntennaAllocation, Allocation
 from .utils import notify_allocation
@@ -307,9 +311,32 @@ class AntennaAdmin(geo_admin.OSMGeoAdmin):
         AntennaPrefixFilter,
     )
 
+    def get_queryset(self, request):
+        qs = super().get_queryset(request)
+        if connection.vendor == 'postgresql':
+            qs = qs.annotate(
+                    ip=StringAgg( # concaténation des IP avec des virgules directement par postgresql
+                        Cast( # casting en TextField car StringApp oppère sur des string mais les ip sont des inet
+                            models.Case( # seulement les IP des allocations actives
+                                models.When(
+                                    get_active_filter('allocation'),
+                                    then='allocation__resource__ip'
+                                ),
+                            ),
+                            models.TextField()
+                        ),
+                        delimiter=', '
+                    )
+                )
+        return qs
+
     def ip_display(self, obj):
-        allocations = obj.allocations.filter(active=True)
-        return ', '.join(allocations.values_list('resource__ip', flat=True)) or '-'
+        if connection.vendor == 'postgresql':
+            return obj.ip
+        else:
+            # peu efficace car génère une requête par ligne
+            allocations = obj.allocations.filter(active=True)
+            return ', '.join(allocations.values_list('resource__ip', flat=True)) or '-'
     ip_display.short_description = 'IP'
 
     def get_actions(self, request):