Как изменить 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']}

(мне все равно, если символ Юникода u остается или уходит.)

если я это сделаю queryDict.dict(), как полагает сайт Джанго, я теряю дополнительные значения, принадлежащие var1, например:

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

Я думал сделать это:

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

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

10 73

10 ответов:

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

вот что я в конечном итоге с помощью:

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

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

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

обновление:

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': ['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()}

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

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

QueryDict() документация: https://docs.djangoproject.com/en/2.0/ref/request-response/#django.http.QueryDict