Bagaimana cara mengubah QueryDict django menjadi Python Dict?

111

Anggap saja saya memiliki QueryDict berikut:

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

Saya ingin memiliki kamus tentang ini, misalnya:

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

(Saya tidak peduli jika simbol unicode u tetap atau hilang.)

Jika saya melakukannya queryDict.dict(), seperti yang disarankan oleh situs django , saya kehilangan nilai ekstra yang dimiliki var1, misalnya:

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

Saya berpikir untuk melakukan ini:

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

Apakah ada cara yang lebih baik?

SaiyanGirl
sumber

Jawaban:

103

Ini harus bekerja: myDict = dict(queryDict.iterlists())

Alexandre Vassalotti
sumber
4
queryDict.iterlists () membuat nilai daftar dari setiap kunci, mungkin karena Anda daftar spekt ?, queryDict.iteritems () jika Anda tahu bahwa querydict tidak berisi daftar.
panchicore
3
Dalam django 1.6: dict (data._iteritems ())
Bas Koopmans
5
Di Django 1.6, dict(queryDict.lists())tampaknya berfungsi
Dan Passaro
39
Di Django 1.8 pada Python 3 yang saya butuhkan hanyalah dict(queryDict).
fmalina
1
Ini tidak berfungsi untuk banyak pustaka termasuk authomatic. Lihat pertanyaan saya dan jawaban saya sendiri di sini (bekerja dengan python v2 dan v3): stackoverflow.com/questions/37026535/…
Olivier Pons
193

Baru di Django> = 1.4.

QueryDict.dict()

https://docs.djangoproject.com/en/stable/ref/request-response/#django.http.QueryDict.dict

panchicore
sumber
Dua cara untuk mencari tahu, mencobanya, atau melihat sumbernya. Jawabannya adalah tidak: def dict (self): "" "Mengembalikan objek saat ini sebagai dict dengan nilai singular." "" Return dict ((key, self [key]) for key in self)
dalore
6
Meskipun ini memecahkan masalah untuk beberapa orang yang datang ke halaman ini dari google, itu tidak menjawab pertanyaan OP yang secara eksplisit meminta untuk mempertahankan beberapa nilai untuk sebuah kunci.
kerusuhan
1
Terima kasih Tuhan untuk jawaban ini. Saya sangat tidak mengerti
Nic Wanavit
Bekerja pada Django 1,11
jobima
16

Inilah yang akhirnya saya gunakan:

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

Dari penggunaan saya, ini tampaknya memberi Anda daftar yang dapat Anda kirim kembali ke misalnya pembuat formulir.

EDIT: mungkin ini bukan metode terbaik. Tampaknya jika Anda ingin misalnya menulis QueryDictke file untuk alasan gila apa pun, QueryDict.urlencode()adalah cara yang tepat. Untuk merekonstruksi QueryDictAnda cukup melakukannya QueryDict(urlencoded_data).

Dan Passaro
sumber
3
Metode ini menderita perilaku tak tentu; dalam situasi di mana kunci tertentu mungkin memiliki satu atau lebih nilai, Anda terkadang bisa mendapatkan string, dan terkadang mendapatkan daftar string.
Asherah
8
from django.utils import six 
post_dict = dict(six.iterlists(request.POST))
ytyng
sumber
6

Jika Anda tidak menginginkan nilai sebagai Array, Anda dapat melakukan hal berikut:

# 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 adalah alat yang ampuh, baca lebih lanjut di sini http://docs.python.org/2/library/functions.html#zip

krichard
sumber
2
Saya tahu ini hampir berusia 6 tahun, hanya menunjukkan kepada siapa pun yang mencapai jawaban ini: Di ​​Django> = 2.0 (mungkin bekerja di versi yang lebih lama juga, itu hanya yang saya gunakan), Anda dapat melakukan QueryDict.dict()(yaitu request.POST.dict()) dan itu akan mengembalikan nilai dengan benar.
Luca Bezerra
Luca Anda adalah seorang legenda. Ini membuatku gila sepanjang hari! Hanya jawaban Anda yang bisa saya gunakan untuk bekerja.
scottapotamus
4

Saya mengalami masalah serupa, ingin menyimpan nilai arbitrer dari bentuk sebagai nilai berseri.

Jawaban saya menghindari pengulangan konten kamus secara eksplisit: dict(querydict.iterlists())

Untuk mengambil nilai seperti kamus yang berfungsi seperti aslinya, fungsi inversi digunakan QueryDict.setlist()untuk mengisi nilai baruQueryDict nilai . Dalam kasus ini, menurut saya iterasi eksplisit tidak dapat dihindari.

Fungsi helper saya terlihat seperti ini:

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
Graham Klyne
sumber
3

Memperbarui:

myDict = dict(queryDict._iterlists())

Harap Dicatat: garis bawahi _dalam metode iterlists dari queryDict. Versi Django: 1.5.1

Parthyz
sumber
3

dict(request.POST) mengembalikan kamus python aneh dengan nilai yang dibungkus array.

{'start': ['2017-01-14T21:00'], 'stop': ['2017-01-14T22:00'], 'email': ['[email protected]']}

dimana sebagai {x:request.POST.get(x) for x in request.POST.keys()}hasil keluaran yang diharapkan.

{'start': '2017-01-14T21:00', 'stop': '2017-01-14T22:00', 'email': '[email protected]'}
Sandeep
sumber
Dalam Django> = 2.0 (mungkin bekerja pada versi yang lebih lama juga, itu hanya yang saya gunakan), Anda dapat melakukan QueryDict.dict()(yaitu request.POST.dict()) dan ini akan mengembalikan nilai dengan benar.
Luca Bezerra
2

cukup tambahkan saja

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

Dalam tampilan dan data Anda akan disimpan di querDict sebagai python Dict.

omkar yadav
sumber
1

Beginilah cara saya memecahkan masalah itu:

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

Seperti saya, Anda mungkin lebih akrab dengan Dict()metode dalam python. Namun, QueryDict()ini juga merupakan objek yang mudah digunakan. Misalnya, mungkin Anda ingin mendapatkan nilai darirequest.GET QueryDict() .

Anda dapat melakukan ini seperti: request.GET.__getitem__(<key>).

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

Marquistador
sumber
1
Hindari menggunakan metode garis bawah ganda. Cara yang lebih pythonic adalah dengan menggunakan request.GET.get(<key>)ataurequest.GET.getlist(<key>)
Bobort
1

Dengan Django 2.2ada beberapa solusi bersih:

  1. QueryDict.dict()paling sederhana tetapi akan rusak QueryDictdengan daftar sebagai nilai, misalnya:
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)

akan mengeluarkan

a two  # <--- missed 'one'
b three
  1. dict(QueryDict) lebih baik karena akan membuat kamus daftar yang benar:
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)

akan mengeluarkan

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

yang mana yang benar.

valex
sumber
0

Saya mencoba keduanya dict(request.POST)dan request.POST.dict()dan menyadari bahwa jika Anda memiliki listnilai misalnya 'var1':['value1', 'value2']bersarang di Anda request.POST, later ( request.POST.dict()) hanya memberi saya akses ke item terakhir dalam daftar bersarang sementara yang sebelumnya ( dict(request.POST)) memungkinkan saya mengakses semua item dalam daftar bersarang.

Saya harap ini membantu seseorang.

Codebender
sumber