Skip to content

Commit a396ca8

Browse files
author
Andrew Guenther
committed
[fix] Add schema generation support for plain GeometryFields #257
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
1 parent 6679f3d commit a396ca8

File tree

4 files changed

+76
-2
lines changed

4 files changed

+76
-2
lines changed

rest_framework_gis/schema.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from rest_framework.schemas.openapi import AutoSchema
55
from rest_framework.utils import model_meta
66

7-
from rest_framework_gis.fields import GeometrySerializerMethodField
7+
from rest_framework_gis.fields import GeometryField, GeometrySerializerMethodField
88
from rest_framework_gis.serializers import (
99
GeoFeatureModelListSerializer,
1010
GeoFeatureModelSerializer,
@@ -110,6 +110,12 @@ def map_field(self, field):
110110
if isinstance(field, GeoFeatureModelListSerializer):
111111
return self._map_geo_feature_model_list_serializer(field)
112112

113+
if isinstance(field, GeometryField):
114+
return {
115+
"type": "object",
116+
"properties": self._map_geo_field(field.parent, field.field_name),
117+
}
118+
113119
return super().map_field(field)
114120

115121
def _map_geo_feature_model_list_serializer(self, serializer):

tests/django_restframework_gis_tests/serializers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ class Meta:
203203
fields = '__all__'
204204

205205

206+
class PolygonModelSerializer(serializers.ModelSerializer):
207+
class Meta:
208+
model = PolygonModel
209+
fields = '__all__'
210+
211+
206212
class MultiPolygonSerializer(gis_serializers.GeoFeatureModelSerializer):
207213
class Meta:
208214
model = MultiPolygonModel

tests/django_restframework_gis_tests/test_schema_generation.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
GeojsonLocationContainedInBBoxList,
2828
GeojsonLocationContainedInTileList,
2929
GeojsonLocationWithinDistanceOfPointList,
30+
ModelViewWithPolygon,
3031
geojson_location_list,
3132
)
3233

@@ -608,3 +609,58 @@ def test_distance_to_point_filter(self):
608609
},
609610
],
610611
)
612+
613+
def test_geometry_field(self):
614+
path = "/"
615+
method = "GET"
616+
view = create_view(ModelViewWithPolygon, "GET", create_request("/"))
617+
inspector = GeoFeatureAutoSchema()
618+
inspector.view = view
619+
serializer = inspector.get_serializer(path, method)
620+
content = inspector.map_serializer(serializer)
621+
content.pop("type", None)
622+
623+
self.maxDiff = None
624+
self.assertEqual(
625+
content,
626+
{
627+
"properties": {
628+
"id": {'type': 'integer', 'readOnly': True},
629+
'polygon': {
630+
'properties': {
631+
'coordinates': {
632+
'example': [
633+
[0.0, 0.0],
634+
[0.0, 50.0],
635+
[50.0, 50.0],
636+
[50.0, 0.0],
637+
[0.0, 0.0],
638+
],
639+
'items': {
640+
'example': [[22.4707, 70.0577], [12.9721, 77.5933]],
641+
'items': {
642+
'example': [12.9721, 77.5933],
643+
'items': {'format': 'float', 'type': 'number'},
644+
'maxItems': 3,
645+
'minItems': 2,
646+
'type': 'array',
647+
},
648+
'minItems': 4,
649+
'type': 'array',
650+
},
651+
'type': 'array',
652+
},
653+
'type': {'enum': ['Polygon'], 'type': 'string'},
654+
},
655+
'type': 'object',
656+
},
657+
"random_field1": {"type": "string", "maxLength": 32},
658+
"random_field2": {
659+
"type": "integer",
660+
"maximum": 2147483647,
661+
"minimum": -2147483648,
662+
},
663+
},
664+
"required": ["random_field1", "random_field2", "polygon"],
665+
},
666+
)

tests/django_restframework_gis_tests/views.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
)
1212
from rest_framework_gis.pagination import GeoJsonPagination
1313

14-
from .models import BoxedLocation, LocatedFile, Location, Nullable
14+
from .models import BoxedLocation, LocatedFile, Location, Nullable, PolygonModel
1515
from .serializers import (
1616
BoxedLocationGeoFeatureSerializer,
1717
LocatedFileGeoFeatureSerializer,
@@ -24,6 +24,7 @@
2424
LocationGeoSerializer,
2525
NoneGeoFeatureMethodSerializer,
2626
PaginatedLocationGeoSerializer,
27+
PolygonModelSerializer,
2728
)
2829

2930

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

248249

249250
geojson_nullable_details = GeojsonNullableDetails.as_view()
251+
252+
253+
class ModelViewWithPolygon(generics.RetrieveUpdateDestroyAPIView):
254+
model = PolygonModel
255+
serializer_class = PolygonModelSerializer

0 commit comments

Comments
 (0)