#35449: SplitArrayField doesn't validate properly (django.contrib.postgres.forms) --------------------------------------------+------------------------ Reporter: Matthijs | Owner: (none) Type: Bug | Status: new Component: contrib.postgres | Version: 4.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 | --------------------------------------------+------------------------ I created an {{{ArrayField(models.CharField(), size=3)}}} on one of my models and created a form for it using the {{{SplitArrayField}}}. My requirements where that the array field was optional to fill in and that you could also just fill in one of the CharFields and leave the others blank. So according to [https://docs.djangoproject.com/en/4.2/ref/contrib/postgres/forms/#django.contrib.postgres.forms.SplitArrayField.remove_trailing_nulls the docs] I was to set the {{{CharField}}} in my {{{SplitArrayField}}} to {{{required=True}}} and {{{remove_trailing_nulls=True}}} on the {{{SplitArrayField}}}. {{{ SplitArrayField( forms.CharField(required=True, max_length=148), size=3, widget=SplitArrayWidget(forms.TextInput(attrs={'size': '148'}), 3), remove_trailing_nulls=True, required=False ) }}}
To my surprise the form did not validate properly and I was able to submit inputs that exceeded the {{{max_length}}} specified in my form. Looking at the {{{def clean}}} method of the {{{SplitArrayField}}} I suspect a problem there. {{{ try: cleaned_data.append(self.base_field.clean(item)) except ValidationError as error: errors.append( prefix_validation_error( error, self.error_messages["item_invalid"], code="item_invalid", params={"nth": index + 1}, ) ) cleaned_data.append(None) ... }}} If there is any {{{ValidationError}}} the error is added to {{{errors}}}, at the same time {{{None}}} is appended to the {{{cleaned_data}}}. This causes issues with the {{{self._remove_trailing_nulls}}} later on. {{{ cleaned_data, null_index = self._remove_trailing_nulls(cleaned_data) if null_index is not None: errors = errors[:null_index] errors = list(filter(None, errors)) }}} {{{cleaned_data}}} is passed to {{{self._remove_trailing_nulls}}} and because {{{remove_trailing_nulls=True}}}, {{{null_index}}} will be {{{0}}} thus {{{errors}}} is reassigned to an empty list. I wrote a test case showcasing this issue: {{{ from django import forms from django.contrib.postgres.forms import SplitArrayField class TestForm1(forms.Form): field = SplitArrayField( forms.CharField(max_length=5, required=True), size=3, remove_trailing_nulls=True, required=False, ) class TestForm2(forms.Form): field = forms.CharField(max_length=5, required=True) class SplitArrayFieldTest(TestCase): def test_validation_error(self): invalid_value = 'invalid' form1 = TestForm1(data={'field': [invalid_value, '', '']}) form2 = TestForm2(data={'field': invalid_value}) self.assertFalse(form1.is_valid()) #is_valid() should return False, but returns True self.assertFalse(form2.is_valid()) }}} -- Ticket URL: <https://code.djangoproject.com/ticket/35449> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/0107018f761633b8-991d65c0-9681-45fe-a680-2242704c8bc6-000000%40eu-central-1.amazonses.com.