#28748: Named groups in choices are not properly validated
-------------------------------------+-------------------------------------
Reporter: Scott | Owner: nobody
Stevens |
Type: Bug | Status: new
Component: Database | Version: 2.0
layer (models, ORM) |
Severity: Normal | Keywords: choices
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
When using named groups for the `choices` attribute, I accidentally
created them incorrectly, like so:
{{{
tournament = models.PositiveSmallIntegerField(db_index=True, choices=(
(4, 'g'),
('NamedTuple', (5, 'h'), ),
))
}}}
Given that specifying `choices` as `(4, 'g'), ('NamedTuple', (5, 'h'), (6,
'i'), ),` raises `E.005` (as does `1, 2, 3,`), I would expect the same
result for these malformed named groups.
Instead, it allows `./manage.py makemigrations` to run successfully (the
check is not performed when launching `./manage.py shell`, which might be
its own issue). However, it raises this exception when performing a
`full_clean()` on a model and thus validating the field in question
(assuming the field has been set):
{{{
File "...\django\db\models\base.py", line 1144, in full_clean
self.clean_fields(exclude=exclude)
File ...\django\db\models\base.py", line 1186, in clean_fields
setattr(self, f.attname, f.clean(raw_value, self))
File "...\django\db\models\fields\__init__.py", line 607, in clean
self.validate(value, model_instance)
File "...\django\db\models\fields\__init__.py", line 583, in validate
for optgroup_key, optgroup_value in option_value:
TypeError: 'int' object is not iterable
}}}
The `flatchoices` attribute ends up as `[5, 'h', (4, 'g')]`.
It is my understanding that this behaviour is unintended, as the
`_check_choices()` method performs validation on the `choices` attribute.
Specifically, this clause
{{{
elif any(isinstance(choice, str) or
not is_iterable(choice) or len(choice) != 2
for choice in self.choices):
return [
checks.Error(
"'choices' must be an iterable containing "
"(actual value, human readable name) tuples.",
obj=self,
id='fields.E005',
)
]
}}}
Does not check beyond the length of each choice, even if that "choice" is
a named group.
This can be further seen with this set of choices:
{{{
tournament = models.PositiveSmallIntegerField(db_index=True, choices=(
(4, 'g'),
('NamedTuple', (
(5, 'h'),
(2, 3, 4, ),
)),
))
}}}
Migrations are again created successfully, but when validating the field,
it raises
{{{ ValueError: too many values to unpack (expected 2) }}}
on the same line as before.
--
Ticket URL: <https://code.djangoproject.com/ticket/28748>
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/052.d5c6e029ea9871501d702df7fcaea507%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.