From 8198f63b706a9790933fa4b7575d6d3da383875f Mon Sep 17 00:00:00 2001 From: Gagaro Date: Tue, 5 Dec 2017 11:50:07 +0100 Subject: [PATCH] django 2.0 compatibility --- djgeojson/serializers.py | 25 +++++++++++++++++++------ djgeojson/tests.py | 28 ++++++++++++++++------------ djgeojson/views.py | 11 ++++++++++- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/djgeojson/serializers.py b/djgeojson/serializers.py index 496a59b..f3f8468 100644 --- a/djgeojson/serializers.py +++ b/djgeojson/serializers.py @@ -56,6 +56,14 @@ def hasattr_lazy(obj, name): return name in dir(obj) +def get_field_remote_field(field): + """ For Django 1.8/2.0 compatibility """ + if django.VERSION < (1, 9): + return field.rel + else: + return field.remote_field + + class DjangoGeoJSONEncoder(DjangoJSONEncoder): def default(self, o): @@ -321,17 +329,22 @@ def handle_fk_field(self, obj, field): if self.use_natural_keys and hasattr(related, 'natural_key'): related = related.natural_key() else: - if field.rel.field_name == related._meta.pk.name: + if get_field_remote_field(field).field_name == related._meta.pk.name: # Related to remote object via primary key related = related._get_pk_val() else: # Related to remote object via other field - related = smart_text(getattr(related, field.rel.field_name), strings_only=True) + related = smart_text(getattr(related, get_field_remote_field(field).field_name), strings_only=True) self._current['properties'][field.name] = related def handle_m2m_field(self, obj, field): - if field.rel.through._meta.auto_created: - if self.use_natural_keys and hasattr(field.rel.to, 'natural_key'): + if get_field_remote_field(field).through._meta.auto_created: + remote_field = get_field_remote_field(field) + if django.VERSION < (1, 9): # Django 1.8/2.0 compatibility + remote_model = remote_field.to + else: + remote_model = remote_field.related_model + if self.use_natural_keys and hasattr(remote_model, 'natural_key'): def m2m_value(value): return value.natural_key() else: @@ -413,7 +426,7 @@ def serialize_queryset(self, queryset): continue if field.serialize or field.primary_key: - if field.rel is None: + if get_field_remote_field(field) is None: if self.properties is None or field.attname in self.properties: self.handle_field(obj, field.name) else: @@ -427,7 +440,7 @@ def serialize_queryset(self, queryset): for field in reversed_fields: if field.serialize: - field_name = field.rel.related_name or opts.object_name.lower() + field_name = get_field_remote_field(field).related_name or opts.object_name.lower() if self.properties is None or field_name in self.properties: self.handle_reverse_field(obj, field, field_name) self.end_object(obj) diff --git a/djgeojson/tests.py b/djgeojson/tests.py index 4ba4374..8ec8e7d 100644 --- a/djgeojson/tests.py +++ b/djgeojson/tests.py @@ -2,6 +2,7 @@ import json +import django from django.test import TestCase from django.conf import settings from django.core import serializers @@ -26,10 +27,21 @@ def picture(self): return 'image.png' +class Country(models.Model): + label = models.CharField(max_length=20) + geom = models.PolygonField(spatial_index=False, srid=4326) + + if django.VERSION < (1, 9): + objects = models.GeoManager() + + def natural_key(self): + return self.label + + class Route(PictureMixin, models.Model): name = models.CharField(max_length=20) geom = models.LineStringField(spatial_index=False, srid=4326) - countries = models.ManyToManyField('Country') + countries = models.ManyToManyField(Country) def natural_key(self): return self.name @@ -38,12 +50,13 @@ def natural_key(self): def upper_name(self): return self.name.upper() - objects = models.GeoManager() + if django.VERSION < (1, 9): + objects = models.GeoManager() class Sign(models.Model): label = models.CharField(max_length=20) - route = models.ForeignKey(Route, related_name='signs') + route = models.ForeignKey(Route, related_name='signs', on_delete=models.PROTECT) def natural_key(self): return self.label @@ -53,15 +66,6 @@ def geom(self): return self.route.geom.centroid -class Country(models.Model): - label = models.CharField(max_length=20) - geom = models.PolygonField(spatial_index=False, srid=4326) - objects = models.GeoManager() - - def natural_key(self): - return self.label - - class GeoJsonDeSerializerTest(TestCase): def test_basic(self): diff --git a/djgeojson/views.py b/djgeojson/views.py index 814df6c..fc4b495 100644 --- a/djgeojson/views.py +++ b/djgeojson/views.py @@ -1,5 +1,11 @@ import math +import django + +try: + from django.contrib.gis.db.models.functions import Intersection +except ImportError: + pass from django.views.generic import ListView from django.utils.decorators import method_decorator from django.views.decorators.gzip import gzip_page @@ -142,7 +148,10 @@ def get_queryset(self): self.trim_to_boundary = (self.trim_to_boundary and not isinstance(model_field, PointField)) if self.trim_to_boundary: - qs = qs.intersection(bbox) + if django.VERSION < (1, 9): + qs = qs.intersection(bbox) + else: + qs = qs.annotate(intersection=Intersection(self.geometry_field, bbox)) self.geometry_field = 'intersection' return qs