如何将Django QueryDict更改为Python Dict?


111

假设我有以下QueryDict:

<QueryDict: {u'num': [0], u'var1': [u'value1', u'value2'], u'var2': [u'8']}>

我想要一本这样的字典,例如:

{'num': [0], 'var1':['value1', 'value2'], 'var2':['8']}

(我不在乎Unicode符号是否u继续存在。)

如果我queryDict.dict()按照django网站的建议进行操作,则会丢失属于的额外值var1,例如:

{'num': [0], 'var1':['value2'], 'var2':['8']}

我正在考虑这样做:

myDict = {}
for key in queryDict.iterkeys():
    myDict[key] = queryDict.getlist(key)

有没有更好的办法?

Answers:


103

这应该工作: myDict = dict(queryDict.iterlists())


4
queryDict.iterlists()从每个键中生成一个列表值,可能是因为您查看了list ?,如果知道querydict不包含列表,则使用queryDict.iteritems()。
panchicore

3
在Django 1.6中:dict(data._iteritems())
Bas Koopmans

5
在Django 1.6,dict(queryDict.lists())似乎工作
丹Passaro

39
在Python 3上的Django 1.8中,我只需要dict(queryDict)
fmalina

1
这不适用于包括授权库在内的许多库。见我的问题,我自己的答案在这里(与V2和Python的V3作品):stackoverflow.com/questions/37026535/...
奥利维尔·庞斯

193

找出,尝试或查看源的两种方法。答案是否定的:def dict(self):“”“将当前对象作为具有奇异值的dict返回。”“”返回dict((key in self [key,self [key])for key in self)
dalore

6
虽然这为从Google进入此页面的一些人解决了问题,但它无法回答OP明确要求为键保留多个值的问题。
暴动

1
感谢上帝的回答。我
太笨了

使用Django 1.11的工作
Jobima

16

这就是我最终使用的:

def qdict_to_dict(qdict):
    """Convert a Django QueryDict to a Python dict.

    Single-value fields are put in directly, and for multi-value fields, a list
    of all values is stored at the field's key.

    """
    return {k: v[0] if len(v) == 1 else v for k, v in qdict.lists()}

根据我的用法,这似乎为您提供了一个列表,您可以将其发送回例如表单构造函数。

编辑:也许这不是最好的方法。看来,如果您QueryDict出于某种疯狂的原因例如要写入文件,这是可行QueryDict.urlencode()的方法。要重建QueryDict您,只需要做QueryDict(urlencoded_data)


3
这种方法的行为不确定。在给定键可能具有一个或多个值的情况下,有时可能会得到一个字符串,有时还会得到一个字符串列表。
Asherah

8
from django.utils import six 
post_dict = dict(six.iterlists(request.POST))

6

如果您不希望这些值作为数组,则可以执行以下操作:

# request = <QueryDict: {u'key': [u'123ABC']}>
dict(zip(request.GET.keys(), request.GET.values()))
{u'key': u"123ABC" }

# Only work for single item lists
# request = <QueryDict: {u'key': [u'123ABC',U 'CDEF']}>
dict(zip(request.GET.keys(), request.GET.values()))
{u'key': u"CDEF" } 

zip是一种功能强大的工具,请在此处详细了解它http://docs.python.org/2/library/functions.html#zip


2
我知道这已经快6年了,只要指出为谁提供以下答案:在Django> = 2.0中(也可以在较旧版本中使用,那只是我正在使用的那个),您可以做到QueryDict.dict()(即request.POST.dict()),并且将正确返回值。
卡·贝塞拉

卢卡,你是一个传奇。这使我整日生气!您的答案是我上班的唯一答案。
scottapotamus

4

我遇到了类似的问题,想将表单中的任意值保存为序列化值。

我的回答避免了显式地迭代字典内容: dict(querydict.iterlists())

为了检索起原始作用的类似于字典的值,可使用反函数QueryDict.setlist()来填充新QueryDict值。在这种情况下,我认为显式迭代是不可避免的。

我的辅助函数如下所示:

from django.http import QueryDict

def querydict_dict(querydict):
    """
    Converts a Django QueryDict value to a regular dictionary, preserving multiple items.
    """
    return dict(querydict.iterlists())

def dict_querydict(dict_):
    """
    Converts a value created by querydict_dict back into a Django QueryDict value.
    """
    q = QueryDict("", mutable=True)
    for k, v in dict_.iteritems():
        q.setlist(k, v)
    q._mutable = False
    return q

3

更新:

myDict = dict(queryDict._iterlists())

请注意:_的iterlists方法中的下划线queryDict。Django版本:1.5.1


3

dict(request.POST) 返回带有数组包装值的怪异python字典。

{'start': ['2017-01-14T21:00'], 'stop': ['2017-01-14T22:00'], 'email': ['sandeep@sakethtech.com']}

作为{x:request.POST.get(x) for x in request.POST.keys()}返回预期输出的位置。

{'start': '2017-01-14T21:00', 'stop': '2017-01-14T22:00', 'email': 'sandeep@sakethtech.com'}

在Django> = 2.0中(也可以在较旧的版本中使用,这只是我正在使用的版本),您可以执行QueryDict.dict()(即request.POST.dict()),它将正确返回值。
卡·贝泽拉

2

只需添加

queryDict=dict(request.GET) 要么 queryDict=dict(QueryDict)

在您的视图中,数据将以python Dict的形式保存在querDict中。


1

这就是我解决该问题的方法:

dict_ = {k: q.getlist(k) if len(q.getlist(k))>1 else v for k, v in q.items()}


1

随着Django 2.2很少有干净的解决方案:

  1. QueryDict.dict()这是最简单的方法,但是会破坏QueryDict列表作为值,例如:
from django.http.request import QueryDict, MultiValueDict

query_dict = QueryDict('', mutable=True)
query_dict.update(MultiValueDict({'a': ['one', 'two']}))
query_dict.update({'b': 'three'})

for key, value in query_dict.dict().items():  # ---> query_dict.dict()
    print(key, value)

将输出

a two  # <--- missed 'one'
b three
  1. dict(QueryDict) 更好,因为它将使列表正确字典:
from django.http.request import QueryDict, MultiValueDict

query_dict = QueryDict('', mutable=True)
query_dict.update(MultiValueDict({'a': ['one', 'two']}))
query_dict.update({'b': 'three'})

for key, value in dict(query_dict).items():  # ---> dict(query_dict)
    print(key, value)

将输出

a ['one', 'two']
b ['three']

哪个是正确的。


0

我尝试了两者dict(request.POST)request.POST.dict()并意识到,如果您的list值中'var1':['value1', 'value2']嵌套了一些值request.POST,则late(request.POST.dict())仅使我可以访问嵌套列表中的最后一项,而前一个(dict(request.POST))则允许我访问嵌套列表中的所有项目。

我希望这可以帮助别人。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.