Django QueryDict, Python Dict'e nasıl dönüştürülür?


111

Aşağıdaki QueryDict'e sahip olduğumu varsayalım:

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

Bundan bir sözlüğe sahip olmak istiyorum, örneğin:

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

(Unicode sembolünün ukalması veya gitmesi umurumda değil .)

Bunu yaparsam queryDict.dict(), django sitesinin önerdiği gibi , ait olan ekstra değerleri kaybederim var1, örneğin:

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

Bunu yapmayı düşünüyordum:

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

Daha iyi bir yol var mı?

Yanıtlar:


103

Bu çalışmalı: myDict = dict(queryDict.iterlists())


4
queryDict.iterlists (), her bir anahtardan bir liste değeri oluşturuyor, çünkü eğer querydict list içermediğini biliyorsanız, belki de listeleri ?, queryDict.iteritems ().
panchicore

3
Django 1.6'da: dict (data._iteritems ())
Bas Koopmans

5
Django 1.6'da dict(queryDict.lists())işe yarıyor gibi görünüyor
Dan Passaro

39
Python 3 üzerindeki Django 1.8'de tek ihtiyacım olan şeydi dict(queryDict).
fmalina

1
Bu, authomatic dahil birçok kitaplık için çalışmaz. Soruma ve kendi cevabıma buradan bakın (python'un v2 ve v3'ü ile çalışır): stackoverflow.com/questions/37026535/…
Olivier Pons

194

Bulmanın, denemenin veya kaynağı görüntülemenin iki yolu. Cevap hayır: def dict (self): "" "Mevcut nesneyi tekil değerlerle bir dikte olarak döndürür." "" Return dict ((key, self [key]) key in self)
dalore

6
Bu, google'dan bu sayfaya gelen bazı kişiler için sorunu çözerken, OP'nin bir anahtar için birden fazla değeri korumayı açıkça isteyen sorusuna cevap vermiyor.
ayaklandı

1
Bu cevap için tanrıya şükür. Çok bilgisizdim
Nic Wanavit

Django 1.11 üzerinde çalışma
jobima

16

Bu benim kullandığım şey:

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

Benim kullanımımdan bu size, örneğin bir form oluşturucuya geri gönderebileceğiniz bir liste veriyor gibi görünüyor.

DÜZENLEME: belki bu en iyi yöntem değildir. Öyle görünüyor ki, örneğin QueryDictçılgın bir sebepten dolayı bir dosyaya yazmak istiyorsanız , QueryDict.urlencode()gidilecek yol budur. Yeniden inşa etmek için QueryDictyapmanız gereken sadece QueryDict(urlencoded_data).


3
Bu yöntem, belirsiz davranıştan muzdariptir; belirli bir anahtarın bir veya daha fazla değere sahip olabileceği bir durumda, bazen bir dize, bazen de bir dizi listesi alabilirsiniz.
Aşera

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

6

Değerleri Dizi olarak istemiyorsanız, aşağıdakileri yapabilirsiniz:

# 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 güçlü bir araçtır http://docs.python.org/2/library/functions.html#zip


2
Bunun neredeyse 6 yaşında olduğunu biliyorum, bu yanıta kim ulaşırsa onu işaret ediyorum: Django> = 2.0'da (eski sürümlerde de çalışabilir, bu sadece benim kullandığım), yapabilirsin QueryDict.dict()(yani request.POST.dict()) ve değerleri düzgün şekilde döndürecektir.
Luca Bezerra

Luca sen bir efsanesin. Bu bütün gün beni deli ediyor! Çalışmak için alabileceğim tek cevap senin.
scottapotamus

4

Bir formdaki keyfi değerleri serileştirilmiş değerler olarak kaydetmek isteyen benzer bir sorunla karşılaştım.

Cevabım, sözlük içeriğini açıkça yinelemekten kaçınıyor: dict(querydict.iterlists())

Orijinal olarak işlev gören sözlüğe benzer bir değer almak için, ters işlev QueryDict.setlist()yeni birQueryDict değeri . Bu durumda, açık yinelemenin önlenebilir olduğunu düşünmüyorum.

Yardımcı işlevlerim şuna benzer:

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

3

Güncelleme:

myDict = dict(queryDict._iterlists())

Lütfen Dikkat: _iterlists yönteminde alt çizgi queryDict. Django sürümü: 1.5.1


3

dict(request.POST) dizi sarılmış değerler içeren garip bir python sözlüğü döndürür.

{'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()}beklenen çıktı olarak nerede dönüyor.

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

Django> = 2.0'da (eski sürümlerde de çalışabilir, bu sadece benim kullandığım), yapabilirsiniz QueryDict.dict()(yani request.POST.dict()) ve değerleri düzgün bir şekilde döndürecektir.
Luca Bezerra

2

sadece ekle

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

Görünümünüzde ve veriler querDict'e python Dict olarak kaydedilecektir.


1

Bu sorunu şu şekilde çözdüm:

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

1

Benim gibi, muhtemelen Dict()python'daki yöntemlere daha aşinasınız . Bununla birlikte, QueryDict()kullanımı kolay bir nesnedir. Örneğin, belki de değerinirequest.GET QueryDict() .

Sen şöyle yapabilirsiniz: request.GET.__getitem__(<key>).

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


1
Çift alt çizgi yöntemlerini kullanmaktan kaçının. Daha pitonik yol kullanmak request.GET.get(<key>)veyarequest.GET.getlist(<key>)
Bobort

1

İle Django 2.2birkaç temiz çözümler vardır:

  1. QueryDict.dict()en basitidir, ancak QueryDictlistelerden değer olarak ayrılacaktır, örneğin:
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)

çıktı verecek

a two  # <--- missed 'one'
b three
  1. dict(QueryDict) daha iyidir, çünkü listelerin doğru sözlüğünü yapacaktır:
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)

çıktı verecek

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

hangisi doğru.


0

Dışarı hem çalıştı dict(request.POST)ve request.POST.dict()varsa o ve fark listörneğin değerlerini 'var1':['value1', 'value2']Gözlerinde farklı iç içe request.POST, daha sonra ( request.POST.dict()) sadece beni (eski ederken yuvalanmış listedeki son öğeye erişmek verdidict(request.POST) ) iç içe geçmiş bir listedeki tüm öğelere erişmek için izin verdi.

Umarım bu birine yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.