Access JSON String in Django Templates Like a Dictionary

One of the reasons I like to use JSONFields in my Django applications is that I can store an entire REST API request body and response body as a JSON object to be accessed like a dictionary later. I would even access it this way in templates to dynamically display data. It’s magical.

However, I’ve recently imported a bunch of data and the JSONField validation managed to import the API responses as strings instead of valid JSON. Why? I don’t know for sure yet but it bothers me.

So I wrote a quick template tag that will process the JSON string and return a dictionary-like object which allows me to parse data the same as before. Beautiful.

# custom_tags.py
import json

from django import template

register = template.Library()


@register.filter(name='jsonify')
def jsonify(data):
    if isinstance(data, dict):
        return data
    else:
        return json.loads(data)


This only requires me to change my template slightly. Here’s what it looked like prior to Django 2.2:

{% for call in api_calls %}
    {% if call.response.specificResponseKey %}
        <p>{{ call.response.specificResponseKey.anotherSpecificKey }}</p>
    {% endif %}
{% endfor %}

And after applying my new template tag:

{% load custom_tags %}

{% for call in api_calls %}
    {% with call.response|jsonify as response %}
        {% if response.specificResponseKey %}
            <p>{{ response.specificResponseKey.anotherSpecificKey }}</p>
        {% endif %}
    {% endwith %}
{% endfor %}

While I could find out why the JSONField didn’t translate the whole API response, which was in valid JSON format, I think this post was more about solving a specific problem in a forward thinking way. Should data be imported improperly again in a way I can’t anticipate, the templatetag will have my back.

py-acc

Backstory

I currently work with an Apple Authorized Reseller, Simply Mac, that is authorized to sell AppleCare+ (AC+) extended warranty plans to its customers. Apple used to have customers manually enroll their extended warranty themselves online after purchase. Nowadays, Apple provides resellers an API to call so that a customer could have their new Apple product enrolled with AC+ before they even leave the store.

To facilitate this, I wrote a custom Django web application that pulls recent AC+ invoices from the Point-of-Sale system using their API, interfaces with Apple’s AppleCare Connect (ACC) REST API, and enrolls the newly purchased AC+ warranty with Apple. This has been working very well for us.

When the request to have automated AC+ enrollments initially came to me, I reviewed Apple’s documentation for the ACC REST API and tried to find if someone had already made a library or module that I could download and use in our application. I was able to find some pre-written code but not for the Python language (which is what Django is written in). So I decided to write a Python module that I could use in our application. This was the first Python module I ever wrote. While I’m not able to open source the full application we use for AC+ enrollments, I am able to provide the Python module I wrote that does a good portion of the heavy lifting.

The Goods!

py-acc on GitHub is our Python module that interfaces with ACC to verify eligibility with, enroll, cancel, and lookup AC+ warranties. My intent is to allow this to be used, scrutinized, and improved by the Apple Reseller community and Python developers in general.

Let me know what you think!