如何将 django QueryDect 更改为 Python Dect?

假设我有以下 QueryDect:

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

我想从这本书中找出一本字典,例如:

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

(我不在乎 Unicode 符号 u的存在与否。)

如果我按照 Django 网站的建议做 queryDict.dict(),我就会失去属于 var1的额外值,例如:

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

我想这么做:

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

还有更好的办法吗?

128364 次浏览

这个应该可以: myDict = dict(queryDict.iterlists())

如果不希望将值设置为 Array,可以执行以下操作:

# 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

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

我的答案是避免显式迭代字典内容: 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

更新:

myDict = dict(queryDict._iterlists())

请注意: 在 queryDict的迭代表方法中下划 _。 Django 版本: 1.5.1

这就是我最后使用的:

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)

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

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'}

我是这样解决这个问题的:

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

像我一样,您可能更熟悉 python 中的 Dict()方法。但是,QueryDict()也是一个易于使用的对象。例如,您可能希望从 request.GET QueryDict()获取值。

你可以这样做: request.GET.__getitem__(<key>)

QueryDict()文档: https://docs.djangoproject.com/en/2.0/ref/request-response/#django.http.QueryDict

只要简单地加上

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

在您的视图中,数据将以 pythonDect 的形式保存在 querDect 中。

我尝试了 dict(request.POST)request.POST.dict(),发现如果你的 request.POST中嵌套了 list值,例如 'var1':['value1', 'value2'],后者(request.POST.dict())只允许我访问嵌套列表中的最后一个项目,而前者(dict(request.POST))允许我访问嵌套列表中的所有项目。

我希望这能帮到别人。

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']

这是正确的。

你可以用一个简单的把戏

queryDict._mutable = False
# Change queryDict
your_dict = {'num': [0], 'var1':['value1', 'value2'], 'var2':['8']}
queryDict.upate(your_dict)
# reset the state
queryDict._mutable = True

我想这个会对你有更好的帮助: QueryDect 实例是不可变的

    user_obj = get_object_or_404(NewUser,id=id)
if request.method == 'POST':
queryDict = request.POST
data = dict(queryDict)
print(data['user_permissions[]'])
user_obj.user_permissions.clear()
user_obj.user_permissions.set(data['user_permissions[]'])
return HttpResponse('Done')