Skip to content

Commit f2dc812

Browse files
authored
[fix] Deserialize id_field #272
When serializing a model, the value of its `id_field` is written in the `id` attribute of the GeoJSON feature. This behaviour is however not mirrored by the deserialization logic: deserializing a model through GeoFeatureModelSerializer ignores the `id` field set in the given GeoJSON feature. This commit solves this issue by mirroring the serialization logic: - When deserializing a model, the `id` attribute of the GeoJSON feature is written as the `id_field` of the django model. Fixes #272 Signed-off-by: Stephane Restani <[email protected]>
1 parent e2c3365 commit f2dc812

File tree

5 files changed

+46
-0
lines changed

5 files changed

+46
-0
lines changed

rest_framework_gis/serializers.py

+3
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ def unformat_geojson(self, feature):
214214
if 'geometry' in feature:
215215
attrs[self.Meta.geo_field] = feature['geometry']
216216

217+
if self.Meta.id_field and 'id' in feature:
218+
attrs[self.Meta.id_field] = feature['id']
219+
217220
if self.Meta.bbox_geo_field and 'bbox' in feature:
218221
attrs[self.Meta.bbox_geo_field] = Polygon.from_bbox(feature['bbox'])
219222

tests/django_restframework_gis_tests/serializers.py

+11
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ class Meta:
107107
fields = ('name',)
108108

109109

110+
class LocationGeoFeatureWritableIdSerializer(LocationGeoFeatureSerializer):
111+
""" default id attribute """
112+
113+
class Meta:
114+
model = Location
115+
geo_field = 'geometry'
116+
fields = ('id', 'name', 'timestamp')
117+
118+
id = serializers.CharField()
119+
120+
110121
class LocatedFileGeoFeatureSerializer(gis_serializers.GeoFeatureModelSerializer):
111122
""" located file geo serializer """
112123

tests/django_restframework_gis_tests/tests.py

+16
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,22 @@ def test_geojson_false_id_attribute_slug(self):
329329
with self.assertRaises(KeyError):
330330
response.data['id']
331331

332+
def test_post_geojson_id_attribute(self):
333+
self.assertEqual(Location.objects.count(), 0)
334+
data = {
335+
"type": "Feature",
336+
"id": "42",
337+
"properties": {"name": "point"},
338+
"geometry": {"type": "Point", "coordinates": [10.1, 10.1]},
339+
}
340+
url = reverse('api_geojson_location_writable_id_list')
341+
response = self.client.post(
342+
url, data=json.dumps(data), content_type='application/json',
343+
)
344+
self.assertEqual(response.status_code, 201)
345+
self.assertEqual(Location.objects.count(), 1)
346+
self.assertEqual(Location.objects.first().id, 42)
347+
332348
def test_geojson_no_id_attribute_slug(self):
333349
location = Location.objects.create(
334350
name='noid test', geometry='POINT (10.1 10.1)'

tests/django_restframework_gis_tests/urls.py

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
path('<int:pk>', views.location_details, name='api_location_details'),
88
# geojson
99
path('geojson/', views.geojson_location_list, name='api_geojson_location_list'),
10+
path(
11+
'geojson_writable_id/',
12+
views.geojson_location_writable_id_list,
13+
name='api_geojson_location_writable_id_list',
14+
),
1015
path(
1116
'geojson/<int:pk>/',
1217
views.geojson_location_details,

tests/django_restframework_gis_tests/views.py

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
LocationGeoFeatureNoIdSerializer,
2222
LocationGeoFeatureSerializer,
2323
LocationGeoFeatureSlugSerializer,
24+
LocationGeoFeatureWritableIdSerializer,
2425
LocationGeoSerializer,
2526
NoneGeoFeatureMethodSerializer,
2627
PaginatedLocationGeoSerializer,
@@ -57,6 +58,16 @@ class GeojsonLocationList(generics.ListCreateAPIView):
5758
geojson_location_list = GeojsonLocationList.as_view()
5859

5960

61+
class GeojsonLocationWritableIdList(generics.ListCreateAPIView):
62+
model = Location
63+
serializer_class = LocationGeoFeatureWritableIdSerializer
64+
queryset = Location.objects.all()
65+
pagination_class = GeoJsonPagination
66+
67+
68+
geojson_location_writable_id_list = GeojsonLocationWritableIdList.as_view()
69+
70+
6071
class GeojsonLocationContainedInBBoxList(generics.ListAPIView):
6172
model = Location
6273
serializer_class = LocationGeoFeatureSerializer

0 commit comments

Comments
 (0)