Skip to content

Commit a3ddd3d

Browse files
committed
Improved serialization performance between 25% and 29%
1 parent 3204352 commit a3ddd3d

File tree

3 files changed

+22
-18
lines changed

3 files changed

+22
-18
lines changed

rest_framework_gis/fields.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
from django.utils.translation import ugettext_lazy as _
77
from rest_framework.fields import Field, SerializerMethodField
88

9+
from .utils import OrderedDict
10+
911

1012
__all__ = ['GeometryField', 'GeometrySerializerMethodField']
1113

@@ -23,7 +25,7 @@ def __init__(self, **kwargs):
2325
def to_representation(self, value):
2426
if isinstance(value, dict) or value is None:
2527
return value
26-
return JsonDict(GEOSGeometry(value).geojson)
28+
return GeoJsonDict(value)
2729

2830
def to_internal_value(self, value):
2931
if value == '' or value is None:
@@ -47,20 +49,23 @@ def validate_empty_values(self, data):
4749
class GeometrySerializerMethodField(SerializerMethodField):
4850
def to_representation(self, value):
4951
value = super(GeometrySerializerMethodField, self).to_representation(value)
50-
return JsonDict(GEOSGeometry(value).geojson)
52+
return GeoJsonDict(value)
5153

5254

53-
class JsonDict(dict):
55+
class GeoJsonDict(OrderedDict):
5456
"""
55-
Takes GeoDjango geojson in input and converts it _back_ to a Python object
56-
Retains the geojson string for python 2,
57-
see: https://github.com/djangonauts/django-rest-framework-gis/pull/60
58-
59-
TODO: remove this when python 2 will be deprecated
57+
Used for serializing GIS values to GeoJSON values
58+
TODO: remove this when support for python 2.6/2.7 will be dropped
6059
"""
61-
def __init__(self, data):
62-
self._geojson_string = data
63-
super(JsonDict, self).__init__(json.loads(data))
60+
def __init__(self, geometry):
61+
super(GeoJsonDict, self).__init__((
62+
('type', geometry.geom_type),
63+
('coordinates', geometry.coords),
64+
))
6465

6566
def __str__(self):
66-
return self._geojson_string
67+
"""
68+
Avoid { 'type': u'Point', 'coordinates': [12, 32] } in python 2.6/2.7
69+
see: https://github.com/djangonauts/django-rest-framework-gis/pull/60
70+
"""
71+
return json.dumps(self)

rest_framework_gis/serializers.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,17 @@ def to_representation(self, instance):
100100
Serialize objects -> primitives.
101101
"""
102102
ret = OrderedDict()
103-
fields = [field for field in self.fields.values() if not field.write_only]
104103

105104
# geo structure
106-
if self.Meta.id_field is not False:
107-
ret["id"] = ""
108105
ret["type"] = "Feature"
109-
ret["geometry"] = {}
110106
ret["properties"] = OrderedDict()
111107
if self.Meta.bbox_geo_field or self.Meta.auto_bbox:
112108
ret["bbox"] = None
113109

114-
for field in fields:
110+
for field in self.fields.values():
111+
if field.write_only:
112+
continue
113+
115114
field_name = field.field_name
116115
value = field.get_attribute(instance)
117116
value_repr = None

tests/django_restframework_gis_tests/tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ def test_geometry_serializer_method_field(self):
493493
self.assertEqual(response.status_code, 200)
494494
self.assertEqual(response.data['properties']['name'], 'hidden geometry')
495495
self.assertEqual(response.data['geometry']['type'], 'Point')
496-
self.assertEqual(response.data['geometry']['coordinates'], [0.0, 0.0])
496+
self.assertEqual(response.data['geometry']['coordinates'], (0.0, 0.0))
497497

498498
def test_filterset(self):
499499
from rest_framework_gis.filterset import GeoFilterSet

0 commit comments

Comments
 (0)