Skip to content

Instantly share code, notes, and snippets.

@czue
Last active December 15, 2023 21:41
Show Gist options
  • Select an option

  • Save czue/90e287c9818ae726f73f5850c1b00f7f to your computer and use it in GitHub Desktop.

Select an option

Save czue/90e287c9818ae726f73f5850c1b00f7f to your computer and use it in GitHub Desktop.
A simple django template tag that lets you automatically render json from a python object
"""
Usage:
{% load json_tags %}
var = myJsObject = {{ template_var|to_json }};
Features:
- Built in support for dates, datetimes, lazy translations.
- Safe escaping of script tags.
- Support for including QuryDict objects.
- Support for custom serialization methods on objects via defining a `to_json()` method.
"""
import datetime
import json
from decimal import Decimal
from django import template
from django.conf import settings
from django.http import QueryDict
from django.utils.encoding import force_str
from django.utils.functional import Promise
from django.utils.safestring import mark_safe
register = template.Library()
ISO_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
def json_handler(obj):
if callable(getattr(obj, 'to_json', None)):
return obj.to_json()
elif isinstance(obj, datetime.datetime):
return obj.strftime(ISO_DATETIME_FORMAT)
elif isinstance(obj, datetime.date):
return obj.isoformat()
elif isinstance(obj, datetime.time):
return obj.strftime('%H:%M:%S')
elif isinstance(obj, Decimal):
return float(obj) # warning, potential loss of precision
elif isinstance(obj, Promise):
return force_str(obj) # to support ugettext_lazy
else:
return json.JSONEncoder().default(obj)
@register.filter
def to_json(obj):
def escape_script_tags(unsafe_str):
# seriously: http://stackoverflow.com/a/1068548/8207
return unsafe_str.replace('</script>', '<" + "/script>')
# json.dumps does not properly convert QueryDict array parameter to json
if isinstance(obj, QueryDict):
obj = dict(obj)
# apply formatting in debug mode for ease of development
indent = None
if settings.DEBUG:
indent = 2
return mark_safe(escape_script_tags(json.dumps(obj, default=json_handler, indent=indent)))
@Veilkrand

Copy link
Copy Markdown

you need to import settings in order to use settings.debug in line 58.
from django.conf import settings

@czue

czue commented Jan 14, 2021

Copy link
Copy Markdown
Author

oops, thanks! fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment