Fixes #19309: N+1 problem on /interfaces, /ip-addresses and /prefixes requests (#19304)

* Fixes N+1 problem on /interfaces, /ip-addresses and /prefixes requests

* remove extra .all()

* more prefetch for IPAddressViewSet
This commit is contained in:
Andrey Tikhonov 2025-05-06 18:47:44 +02:00 committed by GitHub
parent 94618a9dfb
commit 145ee11a3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 16 additions and 2 deletions

View File

@ -461,6 +461,7 @@ class InterfaceViewSet(PathEndpointMixin, NetBoxModelViewSet):
Interface.objects.select_related("device", "cable"),
],
),
'virtual_circuit_termination',
'l2vpn_terminations', # Referenced by InterfaceSerializer.l2vpn_termination
'ip_addresses', # Referenced by Interface.count_ipaddresses()
'fhrp_group_assignments', # Referenced by Interface.count_fhrp_groups()

View File

@ -1,5 +1,6 @@
from copy import deepcopy
from django.contrib.contenttypes.prefetch import GenericPrefetch
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.db import transaction
from django.shortcuts import get_object_or_404
@ -13,6 +14,7 @@ from rest_framework.response import Response
from rest_framework.routers import APIRootView
from rest_framework.views import APIView
from dcim.models import Interface
from ipam import filtersets
from ipam.models import *
from ipam.utils import get_next_available_prefix
@ -21,6 +23,7 @@ from netbox.api.viewsets.mixins import ObjectValidationMixin
from netbox.config import get_config
from netbox.constants import ADVISORY_LOCK_KEYS
from utilities.api import get_serializer_for_model
from virtualization.models import VMInterface
from . import serializers
@ -79,7 +82,7 @@ class RoleViewSet(NetBoxModelViewSet):
class PrefixViewSet(NetBoxModelViewSet):
queryset = Prefix.objects.all()
queryset = Prefix.objects.prefetch_related("scope")
serializer_class = serializers.PrefixSerializer
filterset_class = filtersets.PrefixFilterSet
@ -100,7 +103,17 @@ class IPRangeViewSet(NetBoxModelViewSet):
class IPAddressViewSet(NetBoxModelViewSet):
queryset = IPAddress.objects.all()
queryset = IPAddress.objects.prefetch_related(
GenericPrefetch(
"assigned_object",
[
# serializers are taken according to IPADDRESS_ASSIGNMENT_MODELS
FHRPGroup.objects.all(),
Interface.objects.select_related("cable", "device"),
VMInterface.objects.select_related("virtual_machine"),
],
),
)
serializer_class = serializers.IPAddressSerializer
filterset_class = filtersets.IPAddressFilterSet