"This field is required" error even on empty inlines formsets in the admin model page, when hiding a choice field of a custom form.
|Reported by:||tyrion.mx@…||Owned by:||nobody|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
I have a custom Form for one of my models (in the example SecondModel) that adds one choice field with an initial value.
If I use that model/form as an inline formset and I exclude the extra field using the "fields" attribute of the ModelAdmin, I got "This Field is required" on all the forms of the formset, including those who where left blank. Here a simple example:
# models.py from django.db import models class FirstModel(models.Model): a = models.CharField(max_length=10) b = models.CharField(max_length=10) class SecondModel(models.Model): link = models.ForeignKey(FirstModel) c = models.CharField(max_length=10) # admin.py from django.contrib import admin from bug.bugged import models, forms class SecondAdmin(admin.TabularInline): model = models.SecondModel form = forms.SecondForm fields = ['c'] extra = 3 class FirstAdmin(admin.ModelAdmin): inlines = [SecondAdmin] admin.site.register(models.FirstModel, FirstAdmin) # forms.py from django import forms from bug.bugged import models DUMMY_CHOICES = ( (0, 'a'), (1, 'b'), (2, 'c') ) class SecondForm(forms.ModelForm): d = forms.IntegerField(label='d', initial=0, widget=forms.Select(choices=DUMMY_CHOICES)) class Meta: model = models.SecondModel
The problem is fields = ['c'], commenting out that line I get no errors.
I guess, this is beacuse of the has_changed check, called by the full_clean method of forms.Form. It happens that changed_data compares the initial "d" value that had been set to 0 with the result of "field.widget.value_from_datadict(self.data,..." that is None because we have not a key for "d" in self.data. So changed_data will contain "d" even if the form has not been changed.
prefixed_name = self.add_prefix(name) data_value = field.widget.value_from_datadict(self.data, self.files, prefixed_name) if not field.show_hidden_initial: initial_value = self.initial.get(name, field.initial)
Change History (5)
comment:1 Changed 5 years ago by jacob
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
- Triage Stage changed from Unreviewed to Accepted