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.