0

I use Django Camel Case to swap from pythons snake_case in the backend to camelCase in the front end, so the keys of the data comply with conventional JavaScript syntax.

This works great for AJAX calls returning JSON.

However often I wish to embed some JSON in an HTML template with Django's standard 'json_script`. I don't wish to use some other JSON strinfier because then it won't be safely escaped.

The problem is that when I embedded the JSON in HTML, it is not camelCased:

Example

# --- models.py ---
from django.db import models

class Foo(models.Model):
    last_name = models.CharField(max_length=250, unique=True)


# --- serializers.py ---
from rest_framework import serializers

class FooSerializer(serializers.ModelSerializer):
    class Meta:
        model = Foo
        fields = ('id', 'last_name')


# --- views.py --- 
from django.views import generic
from . import models

class IndexView(generic.ListView):
    template_name = f"myapp/index.html"
    model = Foo

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['serializer'] = serializers.FooSerializer(self.object_list, many=True)
        return context

Then in the template:

{{ serializer.data|json_script:"FOO_DATA" }}
<script type="module">
    const foos = JSON.parse(document.getElementById('FOO_DATA').textContent);
    console.log(foos)
</script>

But unfortunately it will result in something like:

[{ id: 1, last_name: 'Smith'}, { id: 2, last_name: 'Kent'}]

But I require last_name to be camel cased:

[{ id: 1, lastName: 'Smith'}, { id: 2, lastName: 'Kent'}]

How can one safely embedded JSON data, and convert it to camelCase?

run_the_race
  • 1,344
  • 2
  • 36
  • 62

1 Answers1

0

I ended up creating a custom template filter, can't see an easier way:

from django import template
from django.utils import html
from django.utils.safestring import mark_safe

register = template.Library()


@register.filter()
def camelize_json_script(data, element_id):
    """
    Based on: django.utils.html.json_script

    Escape all the HTML/XML special characters with their unicode escapes, so
    value is safe to be output anywhere except for inside a tag attribute. Wrap
    the escaped JSON in a script tag.
    """
    from djangorestframework_camel_case.render import CamelCaseJSONRenderer

    json_str = CamelCaseJSONRenderer().render(data).decode().translate(html._json_script_escapes)
    return html.format_html(
        '<script id="{}" type="application/json">{}</script>', element_id, mark_safe(json_str)
    )

If you wish to auto load this template tag, you can do so as show here.

run_the_race
  • 1,344
  • 2
  • 36
  • 62