Opened 8 years ago
Closed 8 years ago
#27433 closed Bug (invalid)
ModelForm with BooleanField can not save False/unchecked
Reported by: | Christian Pedersen | Owned by: | Ingo Klöcker |
---|---|---|---|
Component: | Forms | Version: | 1.10 |
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
My model has this field
starred_only = models.BooleanField(default=False)
Overriden in the ModelForm
starred_only = forms.BooleanField(required=False)
Django 1.10 stopped saving the unchecked (False) value. 1.10.1 started doing it again, and from 1.10.2 it stopped.
This fixed it: https://github.com/django/django/pull/7068
And this broke it: https://github.com/django/django/pull/7217
I tried creating a custom widget:
class WorkingCheckboxInput(CheckboxInput): def value_omitted_from_data(self, data, files, name): return True
but value_omitted_from_data is never called.
The docs and/or minor release changelogs doesn't really document how to get the previous default behavior back.
Change History (8)
comment:1 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 8 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
comment:3 by , 8 years ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:4 by , 8 years ago
Resolution: | → needsinfo |
---|---|
Status: | assigned → closed |
comment:5 by , 8 years ago
This also happens in the Django Admin. I can not untick/mark false any records with a BooleanField(default=False)
The form is correctly marked as False, however the model is never updated from True -> False when calling save
comment:6 by , 8 years ago
Resolution: | needsinfo |
---|---|
Status: | closed → new |
comment:7 by , 8 years ago
I also cannot reproduce a problem here. Please more details about how to reproduce it, perhaps with a sample project. How I tried:
class Bool(models.Model): starred_only = models.BooleanField(default=False) class BoolForm(forms.ModelForm): starred_only = forms.BooleanField(required=False) class Meta: fields = '__all__' admin.site.register(Bool, form=BoolForm)
comment:8 by , 8 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
I found the problem. It turns out django-cassandra-engine overrides the construct_instance method.
Change
if (field_has_default and form.add_prefix(f.name) not in form.data and not getattr(form[f.name].field.widget, 'dont_use_model_field_default_for_empty_data', False)): continue
to
if (field_has_default and form[f.name].field.widget.value_omitted_from_data(form.data, form.files, form.add_prefix(f.name))): continue
That explains why it works in 1.10.1 only.
I could not reproduce the problem. The following test passes with Django 1.10.2.
The test fails if I change
to
but I think that's expected behavior.
See also https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#the-save-method (which I think you did already read).
Please provide a test case that demonstrates your bug.