nicer indented json encoding now also in rest api

This commit is contained in:
Laura Klünder 2016-09-13 16:20:37 +02:00
parent 55fc17e872
commit 84bb9ad73a
10 changed files with 62 additions and 40 deletions

View file

@ -0,0 +1,15 @@
from rest_framework.renderers import JSONRenderer
from ..mapdata.utils import json_encoder_reindent
from functools import wraps
orig_render = JSONRenderer.render
@wraps(JSONRenderer.render)
def nicer_renderer(self, data, accepted_media_type=None, renderer_context=None):
if self.get_indent(accepted_media_type, renderer_context) is None:
return orig_render(self, data, accepted_media_type, renderer_context)
return json_encoder_reindent(lambda d: orig_render(self, d, accepted_media_type, renderer_context), data)
# Monkey patch for nicer indentation in the django rest framework
JSONRenderer.render = nicer_renderer

View file

@ -1,5 +1,6 @@
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import BasePermission from rest_framework.permissions import BasePermission

View file

@ -1,4 +1,5 @@
from django.conf import settings from django.conf import settings
from rest_framework import serializers from rest_framework import serializers
from ..editor.hosters import get_hoster_for_package from ..editor.hosters import get_hoster_for_package
@ -6,24 +7,16 @@ from ..mapdata.models import Level, Package, Source
from .permissions import can_access_package from .permissions import can_access_package
class BoundsMixin:
def to_representation(self, obj):
result = super().to_representation(obj)
if obj.bottom is not None:
result['bounds'] = ((obj.bottom, obj.left), (obj.top, obj.right))
return result
class LevelSerializer(serializers.ModelSerializer): class LevelSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Level model = Level
fields = ('name', 'altitude', 'package') fields = ('name', 'altitude', 'package')
class PackageSerializer(BoundsMixin, serializers.ModelSerializer): class PackageSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Package model = Package
fields = ('name', 'home_repo', 'depends') fields = ('name', 'home_repo', 'depends', 'bounds')
def to_representation(self, obj): def to_representation(self, obj):
result = super().to_representation(obj) result = super().to_representation(obj)
@ -36,10 +29,10 @@ class PackageSerializer(BoundsMixin, serializers.ModelSerializer):
return result return result
class SourceSerializer(BoundsMixin, serializers.ModelSerializer): class SourceSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Source model = Source
fields = ('name', 'package') fields = ('name', 'package', 'bounds')
class HosterSerializer(serializers.Serializer): class HosterSerializer(serializers.Serializer):

View file

@ -1,4 +1,5 @@
from django.conf.urls import include, url from django.conf.urls import include, url
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from .views import editor as editor_views from .views import editor as editor_views

View file

@ -1,4 +1,5 @@
from django.http import Http404 from django.http import Http404
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.viewsets import ViewSet from rest_framework.viewsets import ViewSet

View file

@ -4,6 +4,7 @@ import os
from django.conf import settings from django.conf import settings
from django.core.files import File from django.core.files import File
from django.http import HttpResponse from django.http import HttpResponse
from rest_framework.decorators import detail_route from rest_framework.decorators import detail_route
from rest_framework.viewsets import ReadOnlyModelViewSet from rest_framework.viewsets import ReadOnlyModelViewSet

View file

@ -54,6 +54,12 @@ class Package(models.Model):
def package(self): def package(self):
return self return self
@property
def bounds(self):
if self.bottom is None:
return None
return ((float(self.bottom), float(self.left)), (float(self.top), float(self.right)))
def tofile(self): def tofile(self):
data = OrderedDict() data = OrderedDict()
data['name'] = self.name data['name'] = self.name

View file

@ -1,5 +1,3 @@
import json
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -26,11 +24,7 @@ class Source(models.Model):
@property @property
def bounds(self): def bounds(self):
return ((self.bottom, self.left), (self.top, self.right)) return ((float(self.bottom), float(self.left)), (float(self.top), float(self.right)))
@property
def jsbounds(self):
return json.dumps(((float(self.bottom), float(self.left)), (float(self.top), float(self.right))))
@classmethod @classmethod
def fromfile(cls, data, package, name): def fromfile(cls, data, package, name):

View file

@ -3,6 +3,7 @@ import json
from django.core.management.base import CommandError from django.core.management.base import CommandError
from ..models import Level, Package, Source from ..models import Level, Package, Source
from ..utils import json_encoder_reindent
class ObjectCollection: class ObjectCollection:
@ -93,25 +94,5 @@ class ObjectCollection:
print('- Added dependency: '+depname) print('- Added dependency: '+depname)
def _preencode(data, magic_marker):
if isinstance(data, dict):
data = data.copy()
for name, value in tuple(data.items()):
if name in ('bounds', ):
data[name] = magic_marker+json.dumps(value)+magic_marker
else:
data[name] = _preencode(value, magic_marker)
return data
elif isinstance(data, (tuple, list)):
return tuple(_preencode(value, magic_marker) for value in data)
else:
return data
def json_encode(data): def json_encode(data):
magic_marker = '***JSON_MAGIC_MARKER***' return json_encoder_reindent(json.dumps, data, indent=4)+'\n'
test_encode = json.dumps(data)
while magic_marker in test_encode:
magic_marker += '*'
result = json.dumps(_preencode(data, magic_marker), indent=4)
return result.replace('"'+magic_marker, '').replace(magic_marker+'"', '')+'\n'

View file

@ -0,0 +1,29 @@
import json
def _preencode(data, magic_marker):
if isinstance(data, dict):
data = data.copy()
for name, value in tuple(data.items()):
if name in ('bounds', ):
data[name] = magic_marker+json.dumps(value)+magic_marker
else:
data[name] = _preencode(value, magic_marker)
return data
elif isinstance(data, (tuple, list)):
return tuple(_preencode(value, magic_marker) for value in data)
else:
return data
def json_encoder_reindent(method, data, *args, **kwargs):
magic_marker = '***JSON_MAGIC_MARKER***'
test_encode = json.dumps(data)
while magic_marker in test_encode:
magic_marker += '*'
result = method(_preencode(data, magic_marker), *args, **kwargs)
if type(result) == str:
return result.replace('"'+magic_marker, '').replace(magic_marker+'"', '')
else:
magic_marker = magic_marker.encode()
return result.replace(b'"'+magic_marker, b'').replace(magic_marker+b'"', b'')