Как изменить django QueryDict на Python Dict?

Предположим, что у меня есть следующий 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)

Есть ли лучший способ?

Ответ 1

Это должно работать: myDict = dict(queryDict.iterlists())

Ответ 3

Вот что я в итоге использовал:

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

Ответ 4

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

Ответ 5

Если вам не нужны значения в виде массивов, вы можете сделать следующее:

# 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

Ответ 6

Я столкнулся с аналогичной проблемой, желая сохранить произвольные значения из формы как сериализованные значения.

Мой ответ избегает явного итерации содержимого словаря: 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

Ответ 7

Update:

myDict = dict(queryDict._iterlists())

Обратите внимание: подчеркивание _ в методе iterlists queryDict. Версия Django: 1.5.1

Ответ 8

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

Ответ 9

просто добавьте

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

В вашем представлении и данные будут сохранены в querDict как python Dict.

Ответ 10

Как и я, вы, вероятно, более знакомы с методами Dict() в python. Однако QueryDict() также является простым объектом для использования. Например, возможно, вы хотели получить значение из request.GET QueryDict().

Вы можете сделать это так: request.GET.__getitem__(<key>).

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

Ответ 11

Вот как я решил эту проблему:

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

Ответ 12

Я опробовал как dict(request.POST) и request.POST.dict() и понял, что если у вас есть list значений, например 'var1':['value1', 'value2'] вложенных в ваш request.POST, чем позже (request.POST.dict()) предоставил мне доступ только к последнему элементу во вложенном списке, тогда как первый (dict(request.POST)) позволил мне получить доступ ко всем элементам во вложенном списке.

Я надеюсь, что это помогает кому-то.

Ответ 13

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

что правильно.