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.template.response import TemplateResponse
 from django.core.serializers import serialize
 from django.core.serializers import serialize
 from django.http import HttpResponse
 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 adhesions.models import Adhesion
 from .models import Service, ServiceType, IPPrefix, IPResource, Route, Tunnel, ServiceAllocation, Antenna, AntennaAllocation, Allocation
 from .models import Service, ServiceType, IPPrefix, IPResource, Route, Tunnel, ServiceAllocation, Antenna, AntennaAllocation, Allocation
 from .utils import notify_allocation
 from .utils import notify_allocation
@@ -307,9 +311,32 @@ class AntennaAdmin(geo_admin.OSMGeoAdmin):
         AntennaPrefixFilter,
         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):
     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'
     ip_display.short_description = 'IP'
 
 
     def get_actions(self, request):
     def get_actions(self, request):