Fixed #33742 -- Added id to GeoJSON serializer.

This commit is contained in:
Samir Shah 2022-05-28 12:33:15 +03:00 committed by Mariusz Felisiak
parent 9a3b7e5e2b
commit 6f73eb9d90
4 changed files with 26 additions and 1 deletions

View File

@ -13,6 +13,7 @@ class Serializer(JSONSerializer):
def _init_options(self):
super()._init_options()
self.geometry_field = self.json_kwargs.pop("geometry_field", None)
self.id_field = self.json_kwargs.pop("id_field", None)
self.srid = self.json_kwargs.pop("srid", 4326)
if (
self.selected_fields is not None
@ -46,6 +47,7 @@ class Serializer(JSONSerializer):
def get_dump_object(self, obj):
data = {
"type": "Feature",
"id": obj.pk if self.id_field is None else getattr(obj, self.id_field),
"properties": self._current,
}
if (

View File

@ -25,6 +25,9 @@ serializer accepts the following additional option when it is called by
have a model with more than one geometry field and you don't want to use the
first defined geometry field (by default, the first geometry field is picked).
* ``id_field``: A string containing the name of a field to use for the ``id``
key of the GeoJSON feature. By default, the primary key of objects is used.
* ``srid``: The SRID to use for the ``geometry`` content. Defaults to 4326
(WGS 84).
@ -52,6 +55,7 @@ Would output::
'features': [
{
'type': 'Feature',
'id': 1,
'geometry': {
'type': 'Point',
'coordinates': [-87.650175, 41.850385]
@ -66,3 +70,8 @@ Would output::
When the ``fields`` parameter is not specified, the ``geojson`` serializer adds
a ``pk`` key to the ``properties`` dictionary with the primary key of the
object as the value.
.. versionchanged:: 4.2
The ``id`` key for serialized features was added. Also, the ``id_field``
option was added to the ``geojson`` serializer.

View File

@ -53,7 +53,9 @@ Minor features
:mod:`django.contrib.gis`
~~~~~~~~~~~~~~~~~~~~~~~~~
* ...
* The :doc:`GeoJSON serializer </ref/contrib/gis/serializers>` now outputs the
``id`` key for serialized features, which defaults to the primary key of
objects.
:mod:`django.contrib.messages`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -27,6 +27,7 @@ class GeoJSONSerializerTests(TestCase):
self.assertEqual(geodata["features"][0]["geometry"]["type"], "Point")
self.assertEqual(geodata["features"][0]["properties"]["name"], "Chicago")
first_city = City.objects.order_by("name").first()
self.assertEqual(geodata["features"][0]["id"], first_city.pk)
self.assertEqual(geodata["features"][0]["properties"]["pk"], str(first_city.pk))
def test_geometry_field_option(self):
@ -61,6 +62,17 @@ class GeoJSONSerializerTests(TestCase):
geodata = json.loads(geojson)
self.assertEqual(geodata["features"][0]["geometry"]["type"], "Polygon")
def test_id_field_option(self):
"""
By default Django uses the pk of the object as the id for a feature.
The 'id_field' option can be used to specify a different field to use
as the id.
"""
cities = City.objects.order_by("name")
geojson = serializers.serialize("geojson", cities, id_field="name")
geodata = json.loads(geojson)
self.assertEqual(geodata["features"][0]["id"], cities[0].name)
def test_fields_option(self):
"""
The fields option allows to define a subset of fields to be present in