Ответ 1
Это должно работать: myDict = dict(queryDict.iterlists())
Предположим, что у меня есть следующий 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)
Есть ли лучший способ?
Это должно работать: myDict = dict(queryDict.iterlists())
Новое в Django >= 1.4.
QueryDict.dict()
https://docs.djangoproject.com/en/stable/ref/request-response/#django.http.QueryDict.dict
Вот что я в итоге использовал:
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 key.
"""
return {k: v[0] if len(v) == 1 else v for k, v in qdict.lists()}
Из моего использования это, кажется, дает вам список, который вы можете отправить обратно, например. конструктор формы.
EDIT:, возможно, это не лучший метод. Кажется, если вы хотите, например, напишите QueryDict
в файл по какой-то безумной причине, QueryDict.urlencode()
- это путь. Чтобы восстановить QueryDict
, вы просто выполняете QueryDict(urlencoded_data)
.
from django.utils import six
post_dict = dict(six.iterlists(request.POST))
Если вам не нужны значения в виде массивов, вы можете сделать следующее:
# 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
Update:
myDict = dict(queryDict._iterlists())
Обратите внимание: подчеркивание _
в методе iterlists queryDict
. Версия Django: 1.5.1
dict(request.POST)
возвращает странный словарь python с завернутыми массивами значениями.
{'start': ['2017-01-14T21:00'], 'stop': ['2017-01-14T22:00'], 'email': ['[email protected]']}
где as {x:request.POST.get(x) for x in request.POST.keys()}
возвращает ожидаемый результат.
{'start': '2017-01-14T21:00', 'stop': '2017-01-14T22:00', 'email': '[email protected]'}
просто добавьте
queryDict=dict(request.GET)
или queryDict=dict(QueryDict)
В вашем представлении и данные будут сохранены в querDict как python Dict.
Как и я, вы, вероятно, более знакомы с методами Dict()
в python. Однако QueryDict()
также является простым объектом для использования. Например, возможно, вы хотели получить значение из request.GET QueryDict()
.
Вы можете сделать это так: request.GET.__getitem__(<key>)
.
QueryDict()
: https://docs.djangoproject.com/en/2.0/ref/request-response/#django.http.QueryDict
Вот как я решил эту проблему:
dict_ = {k: q.getlist(k) if len(q.getlist(k))>1 else v for k, v in q.items()}
Я опробовал как dict(request.POST)
и request.POST.dict()
и понял, что если у вас есть list
значений, например 'var1':['value1', 'value2']
вложенных в ваш request.POST
, чем позже (request.POST.dict()
) предоставил мне доступ только к последнему элементу во вложенном списке, тогда как первый (dict(request.POST)
) позволил мне получить доступ ко всем элементам во вложенном списке.
Я надеюсь, что это помогает кому-то.
С Django 2.2
есть несколько чистых решений:
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
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']
что правильно.