Skip to content

Commit 3d8eb83

Browse files
Andrew Guentherauvipy
authored andcommitted
[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 3d8eb83

File tree

4 files changed

+75
-2
lines changed

4 files changed

+75
-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: 55 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,57 @@ 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+
622+
self.assertEqual(
623+
content,
624+
{
625+
"type": "object",
626+
"properties": {
627+
"id": {'type': 'integer', 'readOnly': True},
628+
'polygon': {
629+
'properties': {
630+
'coordinates': {
631+
'example': [
632+
[0.0, 0.0],
633+
[0.0, 50.0],
634+
[50.0, 50.0],
635+
[50.0, 0.0],
636+
[0.0, 0.0],
637+
],
638+
'items': {
639+
'example': [[22.4707, 70.0577], [12.9721, 77.5933]],
640+
'items': {
641+
'example': [12.9721, 77.5933],
642+
'items': {'format': 'float', 'type': 'number'},
643+
'maxItems': 3,
644+
'minItems': 2,
645+
'type': 'array',
646+
},
647+
'minItems': 4,
648+
'type': 'array',
649+
},
650+
'type': 'array',
651+
},
652+
'type': {'enum': ['Polygon'], 'type': 'string'},
653+
},
654+
'type': 'object',
655+
},
656+
"random_field1": {"type": "string", "maxLength": 32},
657+
"random_field2": {
658+
"type": "integer",
659+
"maximum": 2147483647,
660+
"minimum": -2147483648,
661+
},
662+
},
663+
"required": ["random_field1", "random_field2", "polygon"],
664+
},
665+
)

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)