Opened 5 years ago
Closed 5 years ago
#32625 closed Uncategorized (invalid)
JSONField with callable default reports ModelForm.has_changed() when it hasn't
| Reported by: | Stuart Kelly | Owned by: | nobody |
|---|---|---|---|
| Component: | Forms | Version: | 3.2 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
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 == []
Change History (1)
comment:1 by , 5 years ago
| Component: | Uncategorized → Forms |
|---|---|
| Resolution: | → invalid |
| Status: | new → closed |
Note:
See TracTickets
for help on using tickets.
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