diff --git a/umap/fields.py b/umap/fields.py index 4798b0b4..8874c964 100644 --- a/umap/fields.py +++ b/umap/fields.py @@ -1,6 +1,7 @@ import json import six +from django.core.serializers.json import DjangoJSONEncoder from django.db import models from django.utils.encoding import smart_str @@ -14,7 +15,7 @@ class DictField(models.TextField): if not value: value = {} if not isinstance(value, six.string_types): - value = json.dumps(value) + value = json.dumps(value, cls=DjangoJSONEncoder) return value def from_db_value(self, value, expression, connection): diff --git a/umap/tests/test_datalayer_views.py b/umap/tests/test_datalayer_views.py index 3fe8a99d..c06f7d20 100644 --- a/umap/tests/test_datalayer_views.py +++ b/umap/tests/test_datalayer_views.py @@ -111,7 +111,7 @@ def test_update(client, datalayer, map, post_data): # Test response is a json j = json.loads(response.content.decode()) assert "id" in j - assert datalayer.pk == j["id"] + assert str(datalayer.pk) == j["id"] assert j["browsable"] is True assert Path(modified_datalayer.geojson.path).exists() diff --git a/umap/urls.py b/umap/urls.py index 09ce7f24..62d8d141 100644 --- a/umap/urls.py +++ b/umap/urls.py @@ -85,7 +85,7 @@ i18n_urls += decorated_patterns( name="datalayer_versions", ), re_path( - r"^datalayer/(?P\d+)/(?P" + uuid + r" )/(?P[_\w]+.geojson)$", + r"^datalayer/(?P\d+)/(?P" + uuid + r")/(?P" + uuid + r"[_\w]+.geojson)$", views.DataLayerVersion.as_view(), name="datalayer_version", ), diff --git a/umap/views.py b/umap/views.py index 5c90fe97..3fd8c76d 100644 --- a/umap/views.py +++ b/umap/views.py @@ -23,6 +23,7 @@ from django.contrib.staticfiles.storage import staticfiles_storage from django.core.exceptions import PermissionDenied from django.core.mail import send_mail from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator +from django.core.serializers.json import DjangoJSONEncoder from django.core.signing import BadSignature, Signer from django.core.validators import URLValidator, ValidationError from django.http import ( @@ -314,7 +315,7 @@ class UserDownload(DetailView, SearchMixin): with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file: for map_ in self.get_maps(): umapjson = map_.generate_umapjson(self.request) - geojson_file = io.StringIO(json.dumps(umapjson)) + geojson_file = io.StringIO(json.dumps(umapjson, cls=DjangoJSONEncoder)) file_name = f"umap_backup_{map_.slug}_{map_.pk}.umap" zip_file.writestr(file_name, geojson_file.getvalue()) @@ -353,7 +354,7 @@ class MapsShowCase(View): } geojson = {"type": "FeatureCollection", "features": [make(m) for m in maps]} - return HttpResponse(smart_bytes(json.dumps(geojson))) + return HttpResponse(smart_bytes(json.dumps(geojson, cls=DjangoJSONEncoder))) showcase = MapsShowCase.as_view() @@ -440,7 +441,7 @@ ajax_proxy = AjaxProxy.as_view() def simple_json_response(**kwargs): - return HttpResponse(json.dumps(kwargs), content_type="application/json") + return HttpResponse(json.dumps(kwargs, cls=DjangoJSONEncoder), content_type="application/json") # ############## # @@ -536,7 +537,7 @@ class MapDetailMixin: geojson["properties"] = {} geojson["properties"].update(properties) geojson["properties"]["datalayers"] = self.get_datalayers() - context["map_settings"] = json.dumps(geojson, indent=settings.DEBUG) + context["map_settings"] = json.dumps(geojson, indent=settings.DEBUG, cls=DjangoJSONEncoder) self.set_preconnect(geojson["properties"], context) return context @@ -1100,7 +1101,7 @@ class DataLayerUpdate(FormLessEditMixin, GZipMixin, UpdateView): # Replace the uploaded file by the merged version. self.request.FILES["geojson"].file = BytesIO( - json.dumps(merged).encode("utf-8") + json.dumps(merged, cls=DjangoJSONEncoder).encode("utf-8") ) # Mark the data to be reloaded by form_valid