Search code examples
djangodjango-jsonfield

Unable to save to model with JSONField


I've been at this problem for so long that I'm not even sure where I am with it. I've written the following management command which generates some JSON and saves it using a Django model. Later I have a view which retrieves this JSON and displays it in a URL.

The model is as follows:

from os import name
from django.db import models

# Create your models here.
class Payload(models.Model):
    name = models.CharField(max_length=255)
    json = models.JSONField()

The management command has this:

        nodes = .... # Various logic to generate a dictionary
        links = .... # Various logic to generate a dictionary
        payload = json.dumps({'nodes': nodes, 'links': links})
        print(payload)

        obj = Payload.objects.filter(name='sankey').first()
        if obj:
            obj.json = payload
            result = obj.save()
            if result:
                print('Successfully updated payload')
            else: print('Could not update payload: '+str(result))
        else:
            obj = Payload(name='sankey', json=payload)
            result = obj.save()
            if result:
                print('Saved new payload')
            else: print('Could not create new payload: '+str(result))

    

        self.stdout.write(self.style.SUCCESS('Generatesankeypayload command executed.'))

When I run the command I get:

{"nodes": [{"name": "Jacks Account"}, {"name": "Books"}, {"name": "Coffee & Snacks"}, {"name": "Grooming"}, {"name": "Hobbies"}, {"name": "Personal Gear"}, {"name": "Public Transport"}, {"name": "Jacks Monzo"}, {"name": "Toys"}, {"name": "Janes Account"}, {"name": "Clothing"}, {"name": "Joint Account"}, {"name": "Basic food"}, {"name": "Council tax"}, {"name": "Electricity & Gas"}, {"name": "Mortgage Payments"}], "links": [{"source": 0, "target": 1, "value": "18.98"}, {"source": 0, "target": 2, "value": "7.59"}, {"source": 0, "target": 3, "value": "35.00"}, {"source": 0, "target": 4, "value": "164.98"}, {"source": 0, "target": 5, "value": "300.99"}, {"source": 0, "target": 6, "value": "300.00"}, {"source": 7, "target": 4, "value": "10.99"}, {"source": 7, "target": 8, "value": "22.94"}, {"source": 9, "target": 10, "value": "25.00"}, {"source": 9, "target": 6, "value": "360.00"}, {"source": 11, "target": 12, "value": "641.56"}, {"source": 11, "target": 13, "value": "300.00"}, {"source": 11, "target": 14, "value": "330.00"}, {"source": 11, "target": 15, "value": "3300.00"}]}
Could not update payload: None
Generatesankeypayload command executed.

At some point when playing with the code, the command did save some JSON, but added escape charactors to the database. Here's a screenshot from the Django admin panel:

Django admin panel showing escape characters in a JSONField


Solution

  • Don't use json.dumps() If you use it it will add / and other stuff. You can achieve using dictionary JSONField will handle the serialization like this

    payload = {'nodes': nodes, 'links': links}