diff --git a/umap/fields.py b/umap/fields.py index 8874c964..4e6506ee 100644 --- a/umap/fields.py +++ b/umap/fields.py @@ -1,10 +1,11 @@ import json import six -from django.core.serializers.json import DjangoJSONEncoder from django.db import models from django.utils.encoding import smart_str +from .utils import json_dumps + class DictField(models.TextField): """ @@ -15,7 +16,7 @@ class DictField(models.TextField): if not value: value = {} if not isinstance(value, six.string_types): - value = json.dumps(value, cls=DjangoJSONEncoder) + value = json_dumps(value) return value def from_db_value(self, value, expression, connection): diff --git a/umap/templatetags/umap_tags.py b/umap/templatetags/umap_tags.py index b995df4f..aa7a45c0 100644 --- a/umap/templatetags/umap_tags.py +++ b/umap/templatetags/umap_tags.py @@ -1,9 +1,9 @@ -import json from copy import copy from django import template from django.conf import settings -from django.core.serializers.json import DjangoJSONEncoder + +from umap.utils import json_dumps register = template.Library() @@ -26,7 +26,7 @@ def map_fragment(map_instance, **kwargs): page = kwargs.pop("page", None) or "" unique_id = prefix + str(page) + "_" + str(map_instance.pk) return { - "map_settings": json.dumps(map_settings, cls=DjangoJSONEncoder), + "map_settings": json_dumps(map_settings), "map": map_instance, "unique_id": unique_id, } diff --git a/umap/utils.py b/umap/utils.py index 003b9b01..26cf581d 100644 --- a/umap/utils.py +++ b/umap/utils.py @@ -1,7 +1,9 @@ import gzip +import json import os from django.conf import settings +from django.core.serializers.json import DjangoJSONEncoder from django.urls import URLPattern, URLResolver, get_resolver @@ -162,3 +164,8 @@ def merge_features(reference: list, latest: list, incoming: list): merged.append(item) return merged + + +def json_dumps(obj, **kwargs): + """Utility using the Django JSON Encoder when dumping objects""" + return json.dumps(obj, cls=DjangoJSONEncoder, **kwargs) diff --git a/umap/views.py b/umap/views.py index b43605c6..ef377228 100644 --- a/umap/views.py +++ b/umap/views.py @@ -23,7 +23,6 @@ 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 ( @@ -67,7 +66,14 @@ from .forms import ( UserProfileForm, ) from .models import DataLayer, Licence, Map, Pictogram, Star, TileLayer -from .utils import ConflictError, _urls_for_js, gzip_file, is_ajax, merge_features +from .utils import ( + ConflictError, + _urls_for_js, + gzip_file, + is_ajax, + json_dumps, + merge_features, +) User = get_user_model() @@ -315,7 +321,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, cls=DjangoJSONEncoder)) + geojson_file = io.StringIO(json_dumps(umapjson)) file_name = f"umap_backup_{map_.slug}_{map_.pk}.umap" zip_file.writestr(file_name, geojson_file.getvalue()) @@ -354,7 +360,7 @@ class MapsShowCase(View): } geojson = {"type": "FeatureCollection", "features": [make(m) for m in maps]} - return HttpResponse(smart_bytes(json.dumps(geojson, cls=DjangoJSONEncoder))) + return HttpResponse(smart_bytes(json_dumps(geojson))) showcase = MapsShowCase.as_view() @@ -441,9 +447,7 @@ ajax_proxy = AjaxProxy.as_view() def simple_json_response(**kwargs): - return HttpResponse( - json.dumps(kwargs, cls=DjangoJSONEncoder), content_type="application/json" - ) + return HttpResponse(json_dumps(kwargs), content_type="application/json") # ############## # @@ -539,9 +543,7 @@ class MapDetailMixin: geojson["properties"] = {} geojson["properties"].update(properties) geojson["properties"]["datalayers"] = self.get_datalayers() - context["map_settings"] = json.dumps( - geojson, indent=settings.DEBUG, cls=DjangoJSONEncoder - ) + context["map_settings"] = json_dumps(geojson, indent=settings.DEBUG) self.set_preconnect(geojson["properties"], context) return context @@ -1105,7 +1107,7 @@ class DataLayerUpdate(FormLessEditMixin, GZipMixin, UpdateView): # Replace the uploaded file by the merged version. self.request.FILES["geojson"].file = BytesIO( - json.dumps(merged, cls=DjangoJSONEncoder).encode("utf-8") + json_dumps(merged).encode("utf-8") ) # Mark the data to be reloaded by form_valid