Opened 8 years ago

Closed 8 years ago

Last modified 6 years ago

#26110 closed Bug (duplicate)

Admin form escapes postgres JSONField on ValidationError

Reported by: Rubén Díaz Owned by: nobody
Component: contrib.admin Version: 1.9
Severity: Normal Keywords: jsonfield, admin
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

To reproduce this bug, let's assume we have this model:

class TestModel(models.Model):
    test_url = models.URLField()  # I've chosen URLField as an example but the specific type of field is irrelevant for this issue
    json_field = JSONField(default={})

The model is added to the admin site the standard way (admin.site.register()) so that we can add content easily. Now, if you go and submit the following:

test_urltest
json_field{"hello": "hola"}

It'll trigger an expected ValidationError since it's not a valid URL. When the form is rendered and presented back to the user, the test_url will show the incorrect URL while the json_field will look like this: "{\"hello\": \"hola\"}". If the user corrects the test_url and submits the form again, the json_field that's being stored in the DB will be the escaped one.

I can't say if this only happens with admin forms or any form (e.g. model forms) since I have no time to run proper tests, but I hope this is enough to track down the issue.

Change History (2)

comment:1 by Tim Graham, 8 years ago

Resolution: duplicate
Status: newclosed

Duplicate of #25532

comment:2 by Laurynas Riliskis, 6 years ago

I am running Django 2 and encounter the same problem. The same results are obtained is called though the admin interface.

import uuid
from django.db import models
from django.contrib.postgres.fields import JSONField

class PublishedConsent(models.Model):
    uuid = models.UUIDField(
            default=uuid.uuid4,
            editable=False)
    json = JSONField()

and then running ./manage shell (through the admin interface results are the same):

>>> p = JSONTest.objects.get(instance="4550d7f3a28c4081af5b3ff5ac62ab60")
>>> p.data
'{}'
>>> p.save()
>>> p = JSONTest.objects.get(instance="4550d7f3a28c4081af5b3ff5ac62ab60")
>>> p.data
'"{}"'
>>> p.save()
>>> p = JSONTest.objects.get(instance="4550d7f3a28c4081af5b3ff5ac62ab60")
>>> p.data
'"\\"{}\\""'
>>> p.save()
>>> p = JSONTest.objects.get(instance="4550d7f3a28c4081af5b3ff5ac62ab60")
>>> p.data
'"\\"\\\\\\"{}\\\\\\"\\""'
Last edited 6 years ago by Laurynas Riliskis (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top