diff --git a/requirements-test.txt b/requirements-test.txt index 879b004b..e249bd33 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,4 +1,4 @@ -psycopg2 +psycopg2~=2.8.0 django-filter>=2.0 contexttimer # QA checks diff --git a/rest_framework_gis/schema.py b/rest_framework_gis/schema.py index 1c25f757..4364ca4b 100644 --- a/rest_framework_gis/schema.py +++ b/rest_framework_gis/schema.py @@ -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, @@ -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): diff --git a/tests/django_restframework_gis_tests/serializers.py b/tests/django_restframework_gis_tests/serializers.py index 98b1f40a..4d5be3d9 100644 --- a/tests/django_restframework_gis_tests/serializers.py +++ b/tests/django_restframework_gis_tests/serializers.py @@ -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 diff --git a/tests/django_restframework_gis_tests/test_schema_generation.py b/tests/django_restframework_gis_tests/test_schema_generation.py index f63b4b65..b9c45b5d 100644 --- a/tests/django_restframework_gis_tests/test_schema_generation.py +++ b/tests/django_restframework_gis_tests/test_schema_generation.py @@ -27,6 +27,7 @@ GeojsonLocationContainedInBBoxList, GeojsonLocationContainedInTileList, GeojsonLocationWithinDistanceOfPointList, + ModelViewWithPolygon, geojson_location_list, ) @@ -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"], + }, + ) diff --git a/tests/django_restframework_gis_tests/views.py b/tests/django_restframework_gis_tests/views.py index 179660b2..987547a3 100644 --- a/tests/django_restframework_gis_tests/views.py +++ b/tests/django_restframework_gis_tests/views.py @@ -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, @@ -24,6 +24,7 @@ LocationGeoSerializer, NoneGeoFeatureMethodSerializer, PaginatedLocationGeoSerializer, + PolygonModelSerializer, ) @@ -247,3 +248,8 @@ class GeojsonNullableDetails(generics.RetrieveUpdateDestroyAPIView): geojson_nullable_details = GeojsonNullableDetails.as_view() + + +class ModelViewWithPolygon(generics.RetrieveUpdateDestroyAPIView): + model = PolygonModel + serializer_class = PolygonModelSerializer