Skip to content

Commit

Permalink
[fix] Add schema generation support for plain GeometryFields #257
Browse files Browse the repository at this point in the history
The intial implementation of schema generation only supported
serializers which subclassed GeoFeatureModel*Serializer. This meant that
models which have standalone GeometryFields would not properly generate
a schema. This change adds support for that use case.

Closes #257
  • Loading branch information
Andrew Guenther committed Jul 14, 2021
1 parent 6679f3d commit 99ee740
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 2 deletions.
8 changes: 7 additions & 1 deletion rest_framework_gis/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from rest_framework.schemas.openapi import AutoSchema
from rest_framework.utils import model_meta

from rest_framework_gis.fields import GeometrySerializerMethodField
from rest_framework_gis.fields import GeometryField, GeometrySerializerMethodField
from rest_framework_gis.serializers import (
GeoFeatureModelListSerializer,
GeoFeatureModelSerializer,
Expand Down Expand Up @@ -110,6 +110,12 @@ def map_field(self, field):
if isinstance(field, GeoFeatureModelListSerializer):
return self._map_geo_feature_model_list_serializer(field)

if isinstance(field, GeometryField):
return {
"type": "object",
"properties": self._map_geo_field(field.parent, field.field_name),
}

return super().map_field(field)

def _map_geo_feature_model_list_serializer(self, serializer):
Expand Down
6 changes: 6 additions & 0 deletions tests/django_restframework_gis_tests/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ class Meta:
fields = '__all__'


class PolygonModelSerializer(serializers.ModelSerializer):
class Meta:
model = PolygonModel
fields = '__all__'


class MultiPolygonSerializer(gis_serializers.GeoFeatureModelSerializer):
class Meta:
model = MultiPolygonModel
Expand Down
55 changes: 55 additions & 0 deletions tests/django_restframework_gis_tests/test_schema_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
GeojsonLocationContainedInBBoxList,
GeojsonLocationContainedInTileList,
GeojsonLocationWithinDistanceOfPointList,
ModelViewWithPolygon,
geojson_location_list,
)

Expand Down Expand Up @@ -608,3 +609,57 @@ def test_distance_to_point_filter(self):
},
],
)

def test_geometry_field(self):
path = "/"
method = "GET"
view = create_view(ModelViewWithPolygon, "GET", create_request("/"))
inspector = GeoFeatureAutoSchema()
inspector.view = view
serializer = inspector.get_serializer(path, method)
content = inspector.map_serializer(serializer)

self.assertEqual(
content,
{
"type": "object",
"properties": {
"id": {'type': 'integer', 'readOnly': True},
'polygon': {
'properties': {
'coordinates': {
'example': [
[0.0, 0.0],
[0.0, 50.0],
[50.0, 50.0],
[50.0, 0.0],
[0.0, 0.0],
],
'items': {
'example': [[22.4707, 70.0577], [12.9721, 77.5933]],
'items': {
'example': [12.9721, 77.5933],
'items': {'format': 'float', 'type': 'number'},
'maxItems': 3,
'minItems': 2,
'type': 'array',
},
'minItems': 4,
'type': 'array',
},
'type': 'array',
},
'type': {'enum': ['Polygon'], 'type': 'string'},
},
'type': 'object',
},
"random_field1": {"type": "string", "maxLength": 32},
"random_field2": {
"type": "integer",
"maximum": 2147483647,
"minimum": -2147483648,
},
},
"required": ["random_field1", "random_field2", "polygon"],
},
)
8 changes: 7 additions & 1 deletion tests/django_restframework_gis_tests/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
)
from rest_framework_gis.pagination import GeoJsonPagination

from .models import BoxedLocation, LocatedFile, Location, Nullable
from .models import BoxedLocation, LocatedFile, Location, Nullable, PolygonModel
from .serializers import (
BoxedLocationGeoFeatureSerializer,
LocatedFileGeoFeatureSerializer,
Expand All @@ -24,6 +24,7 @@
LocationGeoSerializer,
NoneGeoFeatureMethodSerializer,
PaginatedLocationGeoSerializer,
PolygonModelSerializer,
)


Expand Down Expand Up @@ -247,3 +248,8 @@ class GeojsonNullableDetails(generics.RetrieveUpdateDestroyAPIView):


geojson_nullable_details = GeojsonNullableDetails.as_view()


class ModelViewWithPolygon(generics.RetrieveUpdateDestroyAPIView):
model = PolygonModel
serializer_class = PolygonModelSerializer

0 comments on commit 99ee740

Please sign in to comment.