Opened 8 years ago

Closed 8 years ago

#26283 closed Bug (fixed)

SplitArrayField failed to validate because remove_trailing_nulls doesn't work properly

Reported by: Mohamad Nour Chawich Owned by: Daniel Quattrociocchi
Component: contrib.postgres Version: 1.8
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

I have this form

class CategoryForm(forms.ModelForm):
    filters = SplitArrayField(SlugField(required=False), required=False, size=10, remove_trailing_nulls=True)

When I try to submit it without any values it fails with the error: "Item 0 in the array did not validate:"
The reason is that on this line 181 in contrib.postgres.forms.array.py

            if null_index:
                cleaned_data = cleaned_data[:null_index]

Obviously in my case the null_index is 0, therefore the cleaned_data is returned as [u'', u'', u'', u'', u'', u'', u'', u'', u'', u''] which fails to look like an empty_values on line 1188 in db.models.base.py

Attachments (1)

26283-test.diff (1022 bytes ) - added by Tim Graham 8 years ago.

Download all attachments as: .zip

Change History (8)

by Tim Graham, 8 years ago

Attachment: 26283-test.diff added

comment:1 by Tim Graham, 8 years ago

I tried to reproduce with a regression test but couldn't. Maybe I got something wrong. Could you check it and provide a failing test?

comment:2 by Mohamad Nour Chawich, 8 years ago

The test you proposed will not fail because you checked for the wrong value

 self.assertEqual(form.cleaned_data, {'array': ['', '']})

You should have checked for an empty array instead as in

 self.assertEqual(form.cleaned_data, {'array': []})

Since all values are considered empty characters remove_trailing_nulls should result in an empty array. Not in an array that has empty values. Such an array doesn't pass the later check of the form here

line 1188 db.models.base.py

            # Skip validation for empty fields with blank=True. The developer
            # is responsible for making sure they have a valid value.
            raw_value = getattr(self, f.attname)
            if f.blank and raw_value in f.empty_values:
                continue

In this case the raw_value is ['' , ''] while it should have been trimmed.

Last edited 8 years ago by Mohamad Nour Chawich (previous) (diff)

comment:3 by Mohamad Nour Chawich, 8 years ago

I solved that by modifying the clean method of SplitArrayField

        if self.remove_trailing_nulls:
            null_index = None
            for i, value in reversed(list(enumerate(cleaned_data))):
                if value in self.base_field.empty_values:
                    null_index = i
                else:
                    break
            if null_index is not None:
                cleaned_data = cleaned_data[:null_index]
                errors = errors[:null_index]

as the 0 index is still a valid index and shouldn't falsify the trimming condition.

comment:4 by Tim Graham, 8 years ago

Easy pickings: set
Triage Stage: UnreviewedAccepted

Oh I see.

comment:5 by Daniel Quattrociocchi, 8 years ago

Owner: set to Daniel Quattrociocchi
Status: newassigned

comment:6 by Daniel Quattrociocchi, 8 years ago

Has patch: set

I have a pull request to offer with the changes suggested from this ticket https://github.com/django/django/pull/6283.

comment:7 by Tim Graham <timograham@…>, 8 years ago

Resolution: fixed
Status: assignedclosed

In 91f87b8:

Fixed #26283 -- Fixed removal of trailing nulls for SplitArrayField.

Note: See TracTickets for help on using tickets.
Back to Top