Enhanced json encoder, available in AjaxCommandsMixin

This commit is contained in:
Ales (Shagi) Zabala Alava 2021-06-10 16:40:15 +02:00
parent 66b77f37ae
commit eb06fdcece
6 changed files with 99 additions and 6 deletions

View File

@ -54,7 +54,7 @@
{% endif %} {% endif %}
<head> <head>
<h2 class="header-title">{% block title %}{{ title }}{% endblock %}</h3> <h2 class="header-title">{% block title %}{{ title }}{% endblock %}</h2>
</head> </head>
<div class="main-content"> <div class="main-content">

View File

@ -1,8 +1,6 @@
from django import forms from django import forms
from django import template from django import template
from django.conf import settings
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.urls import reverse
register = template.Library() register = template.Library()
@ -11,7 +9,6 @@ def base_form_field(field, css=None, container_class='', add_another_url=None, f
if field.is_hidden: if field.is_hidden:
return str(field) return str(field)
classes = field.field.widget.attrs.get('class', '').split(' ') classes = field.field.widget.attrs.get('class', '').split(' ')
classes.append('form-control') classes.append('form-control')
if css: if css:

46
gas/tests/test_utils.py Normal file
View File

@ -0,0 +1,46 @@
import datetime
import json
from django.test import TestCase
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
from model_bakery import baker
from gas import utils
class UtilsTestCase(TestCase):
def test_jsonencoder(self):
users = baker.make('auth.User', _quantity=3)
now = datetime.datetime.now()
today = datetime.date.today()
data = {
'now': now,
'today': today,
'users': User.objects.all().values_list('pk', flat=True),
'lazy_string': _('lazy'),
}
dumped_data = json.dumps(data, cls=utils.JSONEncoder)
recovered_data = json.loads(dumped_data)
self.assertEqual(
recovered_data['now'],
now.strftime('%Y-%m-%d %H:%M')
)
self.assertEqual(
recovered_data['today'],
today.strftime('%Y-%m-%d')
)
self.assertEqual(
len(recovered_data['users']),
3,
)
self.assertEqual(
set(recovered_data['users']),
set(user.pk for user in users),
)
self.assertEqual(
recovered_data['lazy_string'], 'lazy',
)

View File

@ -1,4 +1,5 @@
import json import json
import datetime
from django import forms from django import forms
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -68,6 +69,34 @@ class AjaxCommandTestCase(TestCase):
response = post_view(request) response = post_view(request)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_custom_json_encoder(self):
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return 'datetime'
if isinstance(obj, datetime.date):
return 'date'
return json.JSONEncoder.default(self, obj)
class SampleAjaxView(gviews.AjaxCommandsMixin, View):
def do_test(self):
return self.render_json({
'now': datetime.datetime.now(),
'today': datetime.date.today(),
}, encoder=CustomEncoder)
view = SampleAjaxView.as_view()
request_factory = RequestFactory()
# Command with corresponding "do_" method
request = request_factory.post('some_url', {
'command': 'test',
})
response = view(request)
data = json.loads(response.content)
self.assertEqual(data['now'], 'datetime')
self.assertEqual(data['today'], 'date')
class GASMixinTestCase(TestCase): class GASMixinTestCase(TestCase):
def setUp(self): def setUp(self):

18
gas/utils.py Normal file
View File

@ -0,0 +1,18 @@
import datetime
import json
from django.db.models import QuerySet
from django.utils.functional import Promise
class JSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.strftime('%Y-%m-%d %H:%M')
if isinstance(obj, datetime.date):
return obj.strftime('%Y-%m-%d')
if isinstance(obj, QuerySet):
return list(obj)
if isinstance(obj, Promise):
return str(obj)
return json.JSONEncoder.default(self, obj)

View File

@ -13,6 +13,7 @@ from django.utils.translation import gettext_lazy as _
from django.views.generic import ListView, CreateView, UpdateView, DeleteView from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from . import gas_settings from . import gas_settings
from . import utils
class AjaxCommandsMixin: class AjaxCommandsMixin:
@ -27,8 +28,10 @@ class AjaxCommandsMixin:
handler = getattr(super(), 'post', self.http_method_not_allowed) handler = getattr(super(), 'post', self.http_method_not_allowed)
return handler(request, *args, **kwargs) return handler(request, *args, **kwargs)
def render_json(self, data): def render_json(self, data, encoder=utils.JSONEncoder):
return HttpResponse(json.dumps(data), content_type='application/json') return HttpResponse(
json.dumps(data, indent=2, cls=encoder),
content_type='application/json')
class GASMixin: class GASMixin: