Skip to content

Commit

Permalink
[VNG-Realisatie#210] move has_geo_fields function
Browse files Browse the repository at this point in the history
  • Loading branch information
Sonny Bakker committed Sep 19, 2022
1 parent 2925f7a commit 2865922
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 26 deletions.
25 changes: 1 addition & 24 deletions vng_api_common/inspectors/geojson.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,11 @@
from drf_spectacular.extensions import OpenApiSerializerFieldExtension
from drf_spectacular.plumbing import ResolvedComponent
from rest_framework import serializers
from rest_framework_gis.fields import GeometryField

from vng_api_common.oas import TYPE_ARRAY, TYPE_NUMBER, TYPE_OBJECT, TYPE_STRING


def has_geo_fields(serializer) -> bool:
"""
Check if any of the serializer fields are a GeometryField.
If the serializer has nested serializers, a depth-first search is done
to check if the nested serializers has `GeometryField`\ s.
"""
for field in serializer.fields.values():
if isinstance(field, serializers.Serializer):
has_nested_geo_fields = has_geo_fields(field)
if has_nested_geo_fields:
return True

elif isinstance(field, (serializers.ListSerializer, serializers.ListField)):
field = field.child

if isinstance(field, GeometryField):
return True

return False


class GeometryFieldExtension(OpenApiSerializerFieldExtension):
target_class = GeometryField
target_class = "rest_framework_gis.fields.GeometryField"
match_subclasses = True

def map_serializer_field(self, auto_schema, direction):
Expand Down
27 changes: 27 additions & 0 deletions vng_api_common/inspectors/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django.db import models

from rest_framework import serializers
from rest_framework.utils.model_meta import get_field_info


Expand Down Expand Up @@ -38,3 +39,29 @@ def get_target_field(model: Type[models.Model], field: str) -> Optional[models.F
return get_target_field(relation_info.related_model, "__".join(remaining))

return None


def has_geo_fields(serializer) -> bool:
"""
Check if any of the serializer fields are a GeometryField.
If the serializer has nested serializers, a depth-first search is done
to check if the nested serializers has `GeometryField`\ s.
"""
try:
from rest_framework_gis.fields import GeometryField
except ImportError:
return False

for field in serializer.fields.values():
if isinstance(field, serializers.Serializer):
has_nested_geo_fields = has_geo_fields(field)
if has_nested_geo_fields:
return True

elif isinstance(field, (serializers.ListSerializer, serializers.ListField)):
field = field.child

if isinstance(field, GeometryField):
return True

return False
3 changes: 1 addition & 2 deletions vng_api_common/inspectors/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse
from rest_framework import exceptions, status, viewsets

from vng_api_common.inspectors.geojson import has_geo_fields

from ..constants import HEADER_AUDIT, HEADER_LOGRECORD_ID, VERSION_HEADER
from ..exceptions import Conflict, Gone, PreconditionFailed
from ..geo import DEFAULT_CRS, HEADER_ACCEPT, HEADER_CONTENT, GeoMixin
from ..permissions import BaseAuthRequired, get_required_scopes
from ..serializers import FoutSerializer, ValidatieFoutSerializer
from .cache import CACHE_REQUEST_HEADERS, get_cache_headers, has_cache_header
from .utils import has_geo_fields

logger = logging.getLogger(__name__)

Expand Down

0 comments on commit 2865922

Please sign in to comment.