I may have found a bug in Django but wanted to run it by the core
developers before I filed a ticket. It concerns validation of a
ModelMultipleChoiceField when using a case-insensitive database
collation (in our case, a MySQL database with collation set to
'utf8_general_ci').

First some background: Our application has a feature that allows users
to add or modify objects using an uploaded CSV file. Some of these
objects have short string-based primary keys, so users can reference
them in the CSV using a code name familiar to them instead of an
esoteric auto-increment ID. These exist in the database is all
uppercase, but users often enter them in the CSV with all lowercase
(or sometimes with initial cap).

Since we use model forms to validate the data, this case disparity
causes ModelMultipleChoiceFields to fail validation, even though in
other contexts the strings compare equal, e.g.
Foo.objects.get(pk='bar') and Foo.objects.get(pk='BAR') both succeed
and return the same object.

Looking at the code, it appears that Django does a strict comparison
of values given in a ModelMultipleChoiceField by doing a membership
test:

https://code.djangoproject.com/browser/django/trunk/django/forms/models.py#L1028

However, the same is not true of a ModelChoiceField, which considers a
pk valid if get() succeeds:

https://code.djangoproject.com/browser/django/trunk/django/forms/models.py#L986

This is weirdly inconsistent:

    Foo.objects.create(name='BAR')  # `name` is the pk

    f = ModelChoiceField(queryset=Foo.objects.all())
    f.clean('BAR')  # succeeds
    f.clean('bar')  # succeeds
    f.clean('bAr')  # succeeds

    f = ModelMultipleChoiceField(queryset=Foo.objects.all())
    f.clean(['BAR'])  # succeeds
    f.clean(['bar'])  # FAILS! ValidationError: [u'Select a valid
choice. bar is not one of the available choices.']

This is not an issue with case-sensitive collations like utf8_bin, but
for others it seems like the validation behavior should take collation
into account in a consistent way.

Shall I file a bug?

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to