mirror of
https://github.com/netbox-community/netbox.git
synced 2026-03-25 02:41:43 +01:00
Address PR feedback
This commit is contained in:
@@ -250,13 +250,16 @@ Similarly, you can opt to omit only specific fields by passing the `omit` parame
|
||||
GET /api/dcim/sites/?omit=circuit_count,device_count,virtualmachine_count
|
||||
```
|
||||
|
||||
!!! note "The `omit` paramater was introduced in NetBox v4.5.2."
|
||||
!!! note "The `omit` parameter was introduced in NetBox v4.5.2."
|
||||
|
||||
Strategic use of the `fields` and `omit` parameters can drastically improve REST API performance, as the exclusion of fields which reference related objects reduces the number and compelxity of underlying database queries needed to generate the response.
|
||||
Strategic use of the `fields` and `omit` parameters can drastically improve REST API performance, as the exclusion of fields which reference related objects reduces the number and complexity of underlying database queries needed to generate the response.
|
||||
|
||||
!!! note
|
||||
The `fields` and `omit` parameters should be considered mutually exclusive. If both are passed, `fields` takes precedence.
|
||||
|
||||
#### Brief Format
|
||||
|
||||
Most API endpoints support an optional "brief" format, which returns only a minimal representation of each object in the response. This is useful when you need only a list of available objects without any related data, such as when populating a drop-down list in a form. It's also more convenient than listing out individual fileds via the `fields` or `omit` parameters. As an example, the default (complete) format of a prefix looks like this:
|
||||
Most API endpoints support an optional "brief" format, which returns only a minimal representation of each object in the response. This is useful when you need only a list of available objects without any related data, such as when populating a drop-down list in a form. It's also more convenient than listing out individual fields via the `fields` or `omit` parameters. As an example, the default (complete) format of a prefix looks like this:
|
||||
|
||||
```no-highlight
|
||||
GET /api/ipam/prefixes/13980/
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
from functools import cached_property
|
||||
|
||||
from rest_framework import serializers
|
||||
from rest_framework.utils.serializer_helpers import BindingDict
|
||||
from drf_spectacular.utils import extend_schema_field
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import extend_schema_field
|
||||
from rest_framework import serializers
|
||||
|
||||
from utilities.api import get_related_object_by_attrs
|
||||
from .fields import NetBoxAPIHyperlinkedIdentityField, NetBoxURLHyperlinkedIdentityField
|
||||
@@ -26,9 +25,11 @@ class BaseModelSerializer(serializers.ModelSerializer):
|
||||
:param nested: Set to True if this serializer is being employed within a parent serializer
|
||||
:param fields: An iterable of fields to include when rendering the serialized object, If nested is
|
||||
True but no fields are specified, Meta.brief_fields will be used.
|
||||
:param omit: An iterable of fields to omit from the serialized object
|
||||
"""
|
||||
self.nested = nested
|
||||
self._requested_fields = fields
|
||||
self._include_fields = fields or []
|
||||
self._omit_fields = omit or []
|
||||
|
||||
# Disable validators for nested objects (which already exist)
|
||||
if self.nested:
|
||||
@@ -36,8 +37,8 @@ class BaseModelSerializer(serializers.ModelSerializer):
|
||||
|
||||
# If this serializer is nested but no fields have been specified,
|
||||
# default to using Meta.brief_fields (if set)
|
||||
if self.nested and not fields:
|
||||
self._requested_fields = getattr(self.Meta, 'brief_fields', None)
|
||||
if self.nested and not fields and not omit:
|
||||
self._include_fields = getattr(self.Meta, 'brief_fields', None)
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -63,16 +64,20 @@ class BaseModelSerializer(serializers.ModelSerializer):
|
||||
@cached_property
|
||||
def fields(self):
|
||||
"""
|
||||
Override the fields property to check for requested fields. If defined,
|
||||
return only the applicable fields.
|
||||
Override the fields property to return only specifically requested fields if needed.
|
||||
"""
|
||||
if not self._requested_fields:
|
||||
return super().fields
|
||||
fields = super().fields
|
||||
|
||||
# Include only requested fields
|
||||
if self._include_fields:
|
||||
fields = {
|
||||
k: v for k, v in fields.items() if k in self._include_fields
|
||||
}
|
||||
|
||||
# Remove omitted fields
|
||||
for field_name in set(self._omit_fields):
|
||||
fields.pop(field_name, None)
|
||||
|
||||
fields = BindingDict(self)
|
||||
for key, value in self.get_fields().items():
|
||||
if key in self._requested_fields:
|
||||
fields[key] = value
|
||||
return fields
|
||||
|
||||
@extend_schema_field(OpenApiTypes.STR)
|
||||
|
||||
@@ -5,13 +5,13 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
||||
from django.db import router, transaction
|
||||
from django.db.models import ProtectedError, RestrictedError
|
||||
from django_pglocks import advisory_lock
|
||||
from netbox.constants import ADVISORY_LOCK_KEYS
|
||||
from rest_framework import mixins as drf_mixins
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
|
||||
from netbox.api.serializers.features import ChangeLogMessageSerializer
|
||||
from netbox.constants import ADVISORY_LOCK_KEYS
|
||||
from utilities.api import get_annotations_for_serializer, get_prefetches_for_serializer
|
||||
from utilities.exceptions import AbortRequest
|
||||
from utilities.query import reapply_model_ordering
|
||||
@@ -75,6 +75,7 @@ class BaseViewSet(GenericViewSet):
|
||||
|
||||
@cached_property
|
||||
def field_kwargs(self):
|
||||
"""Return a dictionary of keyword arguments to be passed when instantiating the serializer."""
|
||||
# An explicit list of fields was requested
|
||||
if requested_fields := self.request.query_params.get('fields'):
|
||||
return {'fields': requested_fields.split(',')}
|
||||
|
||||
Reference in New Issue
Block a user