[Django] #32625: JSONField with callable default reports ModelForm.has_changed() when it hasn't

11 views
Skip to first unread message

Django

unread,
Apr 9, 2021, 3:29:13 AM4/9/21
to django-...@googlegroups.com
#32625: JSONField with callable default reports ModelForm.has_changed() when it
hasn't
-----------------------------------------+------------------------
Reporter: Stuart Kelly | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 3.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
The issue is similar to this bug that has been fixed:
https://code.djangoproject.com/ticket/24428 however isn't due to coercion

test case to reproduce (in a new django project/app)

{{{
from django.db import models
from django.forms import ModelForm


class Vehicle(models.Model):
modifications = models.JSONField(default=list, blank=True, null=True)


class VehicleForm(ModelForm):
class Meta:
model = Vehicle
fields = ("modifications", )


def test_vehicle_form():
vehicle = Vehicle.objects.create()
assert vehicle.modifications == []
data = {"modifications": "[]"}
form = VehicleForm(data, instance=vehicle)
assert form.is_valid()
assert not form.has_changed()
}}}

I would expect that test to pass, but it doesn't. I'm not sure exactly
where the error lies, but I have discovered the following:

{{{
field.show_hidden_initial == True
field.to_python(hidden_widget.value_from_datadict(self.data, self.files,
initial_prefixed_name)) == None
}}}
which then fails the check in field.has_changed
{{{
initial_value = initial if initial is not None else ''
data_value = data if data is not None else ''
return initial_value != data_value
}}}
because `data == []`

--
Ticket URL: <https://code.djangoproject.com/ticket/32625>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Apr 12, 2021, 1:44:11 AM4/12/21
to django-...@googlegroups.com
#32625: JSONField with callable default reports ModelForm.has_changed() when it
hasn't
-------------------------------+--------------------------------------

Reporter: Stuart Kelly | Owner: nobody
Type: Uncategorized | Status: closed
Component: Forms | Version: 3.2
Severity: Normal | Resolution: invalid

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => invalid
* component: Uncategorized => Forms


Comment:

Fields with callable defaults use `show_hidden_initial` (renders a hidden
widget with initial value after the widget), that's why you need to pass
initial data to forms, e.g.
{{{
>>> data = {'modifications': '[]', 'initial-modifications': '[]'}
>>> form = VehicleForm(data, instance=vehicle)
>>> form.has_changed()
False
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/32625#comment:1>

Reply all
Reply to author
Forward
0 new messages