简体   繁体   English

如何将 django QueryDict 更改为 Python Dict?

[英]How to change a django QueryDict to Python Dict?

Let's pretend I have the following QueryDict:假设我有以下 QueryDict:

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

I'd like to have a dictionary out of this, eg:我想要一本字典,例如:

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

(I don't care if the unicode symbol u stays or goes.) (我不在乎 unicode 符号u是留下还是消失。)

If I do queryDict.dict() , as suggested by the django site , I lose the extra values belonging to var1 , eg:如果我按照django 站点的建议执行queryDict.dict() ,我会丢失属于var1的额外值,例如:

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

I was thinking of doing this:我正在考虑这样做:

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

Is there a better way?有没有更好的办法?

这应该有效: myDict = dict(queryDict.iterlists())

This is what I've ended up using:这就是我最终使用的:

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()}

From my usage this seems to get you a list you can send back to eg a form constructor.根据我的用法,这似乎为您提供了一个列表,您可以将其发送回例如表单构造函数。

EDIT: maybe this isn't the best method.编辑:也许这不是最好的方法。 It seems if you want to eg write QueryDict to a file for whatever crazy reason, QueryDict.urlencode() is the way to go.看来,如果您想出于任何疯狂的原因将QueryDict写入文件, QueryDict.urlencode()就是要走的路。 To reconstruct the QueryDict you simply do QueryDict(urlencoded_data) .要重建QueryDict ,您只需执行QueryDict(urlencoded_data)

just simply add只需简单地添加

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

In your view and data will be saved in querDict as python Dict.在您的视图中,数据将作为 python Dict 保存在 querDict 中。

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

If you do not want the values as Arrays you can do the following:如果您不希望将值作为数组,您可以执行以下操作:

# 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 is a powerful tool read more about it here http://docs.python.org/2/library/functions.html#zip zip 是一个强大的工具在这里阅读更多关于它http://docs.python.org/2/library/functions.html#zip

I ran into a similar problem, wanting to save arbitrary values from a form as serialized values.我遇到了类似的问题,想将表单中的任意值保存为序列化值。

My answer avoids explicitly iterating the dictionary contents: dict(querydict.iterlists())我的回答避免显式迭代字典内容: dict(querydict.iterlists())

In order to retrieve a dictionary-like value that functions as the original, an inverse function uses QueryDict.setlist() to populate a new QueryDict value.为了检索一个类似于字典的值作为原始值,逆函数使用QueryDict.setlist()来填充一个新的QueryDict值。 In this case, I don't think the explicit iteration is avoidable.在这种情况下,我不认为显式迭代是可以避免的。

My helper functions look like this:我的辅助函数如下所示:

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

Update:更新:

myDict = dict(queryDict._iterlists())

Please Note : underscore _ in iterlists method of queryDict .请注意:queryDict 的queryDict方法中的下划线_ Django version :1.5.1 Django 版本:1.5.1

dict(request.POST) returns a weird python dictionary with array wrapped values. dict(request.POST)返回一个带有数组包装值的奇怪 python 字典。

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

where as {x:request.POST.get(x) for x in request.POST.keys()} returns expected output.其中{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'}

With Django 2.2 there are few clean solutions:使用Django 2.2有几个干净的解决方案:

  1. QueryDict.dict() is simplest but it will broke QueryDict with lists as values, eg: 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)

will output将输出

a two  # <--- missed 'one'
b three
  1. dict(QueryDict) is better because it will make correct dictionary of lists: 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)

will output将输出

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

which is correct.哪个是对的。

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

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

I tried out both dict(request.POST) and request.POST.dict() and realised that if you have list values for example 'var1':['value1', 'value2'] nested in your request.POST , the later( request.POST.dict() ) only gave me access to the last item in a nested list while the former( dict(request.POST) ) allowed me to access all items in a nested list.我尝试了dict(request.POST)request.POST.dict()并意识到如果您的request.POST中嵌套了例如'var1':['value1', 'value2'] list值,则后者( request.POST.dict() ) 只允许我访问嵌套列表中的最后一项,而前者( dict(request.POST) ) 允许我访问嵌套列表中的所有项目。

I hope this helps someone.我希望这可以帮助别人。

Like me, you probably are more familiar with Dict() methods in python.和我一样,你可能更熟悉 Python 中的Dict()方法。 However, the QueryDict() is also an easy object to use.但是, QueryDict()也是一个易于使用的对象。 For example, perhaps you wanted to get the value from the request.GET QueryDict() .例如,也许您想从request.GET QueryDict()中获取值。

You can do this like so: request.GET.__getitem__(<key>) .你可以这样做: request.GET.__getitem__(<key>)

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

You can use a simple trick just你可以使用一个简单的技巧

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

I think this will help you better: This QueryDict instance is immutable我认为这会更好地帮助你: 这个 QueryDict 实例是不可变的

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM