Example:
{{{
from django.utils.datastructures import MultiValueDict
mvdict = MultiValueDict({"number": "54321"})
mapped = map(int, mvdict.getlist("number"))
if 1 in mapped:
print("1 is found with mvdict")
else:
print("1 isn't found with mvdict")
mapped = map(int, mvdict.getlist("number"))
if 54321 in mapped:
print("54321 is found with mvdict")
else:
print("54321 isn't found with mvdict")
single_list = ["54321"]
mapped = map(int, single_list)
if 1 in mapped:
print("1 is found with single list")
else:
print("1 isn't found with single list")
mapped = map(int, single_list)
if 54321 in mapped:
print("54321 is found with single list")
else:
print("54321 isn't found with single list")
}}}
Output:
{{{
1 is found with mvdict
54321 isn't found with mvdict
1 isn't found with single list
54321 is found with single list
}}}
Expected behaviour:
The number 1 is not expected to be found in the list of numbers (which in
this example is only one entry), but 54321 is. This assumes that the key
of the entry exists in the dict and that the mapping function `int`
neither adds nor removes elements due to being able/not able to parse
elements as ints. I'm fairly confident both assumptions are met in the
example, but the expected behaviour is not.
Remarks:
I admit this use case may seem a bit strange, but it did "naturally" come
up with a form where a user could select some objects identified by their
ID and the form, upon submission, checked for the existence of some IDs in
the selected list of IDs in order to do something. My suspicion is that
some form of string conversion takes place or that an exception is
stringified and taken as a return value. Upon checking if an int exists in
the variable, python will then check for the existence of an int in the
string. This would explain why the number 1 is found, as it is likely to
be found, while the number 54321 isn't.
--
Ticket URL: <https://code.djangoproject.com/ticket/32010>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* resolution: => invalid
Comment:
> mvdict = MultiValueDict({"number": "54321"})
This is incorrect usage. If instantiated manually (which is not part of
the documented public API) the value of each item should be a list.
Compare:
{{{
>>> mvdict = MultiValueDict({"number": "54321"})
>>> mvdict.getlist("number")
['5', '4', '3', '2', '1']
>>> mvdict = MultiValueDict({"number": ["54321"]})
>>> mvdict.getlist("number")
['54321']
}}}
Note that the public `QueryDict` handles this as required:
{{{
>>> from django.http import QueryDict
>>> q = QueryDict("number=54321")
>>> q.getlist("number")
['54321']
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/32010#comment:1>
Comment (by Etienne Ott):
It seems that when creating the example above I didn't reproduce any kind
of bug and instead constructed an incorrect use of `MultiValueDict`.
Further digging has revealed that using the membership operator `in` on
generators like `map` is also incorrect usage. The pythonic way is to
check a list made by list comprehension, e.g. `if number in [x for x in
map(int, somelist)]`. My apologies for wasting time with something
unrelated to Django.
--
Ticket URL: <https://code.djangoproject.com/ticket/32010#comment:2>