Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between a QueryDict and MultiValueDict?

I was looking to convert a dict to a QueryDict in my django project. Couple of links exists to explain this (Django: Can I create a QueryDict from a dictionary? and How to change a django QueryDict to Python Dict?). This is my simple dictionary which I want to convert abc = {'a': 1, 'b':[1,2,3]}. I have tried this approach:

from django.http import QueryDict
from django.utils.datastructures import MultiValueDict
abc = { 'a': 1, 'b':[1,2,3]}
mdict = MultiValueDict(abc)
qdict = QueryDict(mdict)

This is the error trace I am getting

/usr/lib/python2.7/urlparse.pyc in parse_qsl(qs, keep_blank_values, strict_parsing)
407     Returns a list, as G-d intended.
408     """
409     pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
410     r = []
411     for name_value in pairs:
AttributeError: 'MultiValueDict' object has no attribute 'split'

Why this has failed and how can I get this done? Also what are the differences between MultiValueDict and QueryDict?

like image 248
Rajesh Kaushik Avatar asked Aug 10 '15 05:08

Rajesh Kaushik


3 Answers

MultiValueDict is a dictionary subclass that can handle multiple values assigned to a key.So you should pass values of dict as list. here, 1->[1].

In an HttpRequest object, the GET and POST attributes are instances of django.http.QueryDict, a dictionary-like class customized to deal with multiple values for the same key. This is necessary because some HTML form elements, notably , pass multiple values for the same key.

The QueryDicts at request.POST and request.GET will be immutable when accessed in a normal request/response cycle. To get a mutable version you need to use .copy().

Then MultiValueDict can be convert to QueryDictas

abc = { 'a': [1], 'b':[1,2,3]}
mdict = MultiValueDict(abc)
qdict = QueryDict('', mutable=True)
qdict.update(mdict)
>>>QueryDict: {u'a': [1], u'b': [1, 2, 3]}>
>>>dict(qdict.iterlists())
{u'a': [1], u'b': [1, 2, 3]}
>>>qdict.getlist('b')
[1, 2, 3]
like image 127
itzMEonTV Avatar answered Sep 20 '22 11:09

itzMEonTV


QueryDict is a specialized class of MultiValueDict, The only major difference between them is that, QueryDict is immutable by default.

To quote from QueryDict docstring:-

A specialized MultiValueDict which represents a query string. A QueryDict can be used to represent GET or POST data. It subclasses MultiValueDict since keys in such data can be repeated, for instance in the data from a form with a field. By default QueryDicts are immutable, though the copy() method will always return a mutable copy.

You can consult code itself - QueryDict code

As far as initialization of query dict from multivalue dict is concerned, QueryDict does not allow passing any dic in __init__. I guess, it is an oversight on their part.

like image 45
hspandher Avatar answered Sep 20 '22 11:09

hspandher


From the definition of django.http.request.QueryDict:

""" A specialized MultiValueDict which represents a query string. A QueryDict can be used to represent GET or POST data. It subclasses MultiValueDict since keys in such data can be repeated, for instance in the data from a form with a field. By default QueryDicts are immutable, though the copy() method will always return a mutable copy. Both keys and values set on this class are converted from the given encoding (DEFAULT_CHARSET by default) to unicode. """

And from the definition of django.utils.datastructures.MultiValueDict:

""" A subclass of dictionary customized to handle multiple values for the same key.

d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']}) d['name'] 'Simon' d.getlist('name') ['Adrian', 'Simon'] d.getlist('doesnotexist') [] d.getlist('doesnotexist', ['Adrian', 'Simon']) ['Adrian', 'Simon'] d.get('lastname', 'nonexistent') 'nonexistent' d.setlist('lastname', ['Holovaty', 'Willison']) This class exists to solve the irritating problem raised by cgi.parse_qs, which returns a list for every key, even though most Web forms submit single name-value pairs. """

So, being a child class MultiValueDict, QueryDict has the additional property of being immutable. And this is the major point of difference.

like image 31
Animesh Sharma Avatar answered Sep 20 '22 11:09

Animesh Sharma