django QueryDictをPython Dictに変更する方法は?


111

次の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)

もっと良い方法はありますか?

回答:


103

これはうまくいくはずです: myDict = dict(queryDict.iterlists())


4
queryDict.iterlists()は各キーからリスト値を作成しています。おそらくリストを見ているためでしょうか?querydictにリストが含まれていないことがわかっている場合はqueryDict.iteritems()です。
panchicore 2013年

3
django 1.6の場合:dict(data._iteritems())
Bas Koopmans

5
Django 1.6では動作するdict(queryDict.lists())ようです
Dan Passaro

39
Python 3のDjango 1.8では、必要なのはだけでしたdict(queryDict)
fmalina

1
これは、authomaticを含む多くのライブラリでは機能しません。:(のpythonのV2およびV3との作品)ここに私の質問と私自身の答えを参照してくださいstackoverflow.com/questions/37026535/...
オリヴィエ・ポンス

193

ソースを確認、試してみる、またはソースを表示する2つの方法。答えはノーです:def dict(self): "" "現在のオブジェクトを特異値を持つdictとして返します。" "" return dict((key、self [key])for key in self)
dalore

6
これにより、Googleからこのページにアクセスする一部の人々の問題は解決しますが、キーの複数の値を保持することを明示的に求めるOPの質問には答えません。
2018

1
この答えを神に感謝します。私はとても無知でした
ニックワナビット

Django 1.11での作業
jobima

16

これは私が最終的に使用したものです:

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

私の使用法から、これはあなたが例えばフォームコンストラクタに送り返すことができるリストを手に入れるようです。

編集:多分これは最良の方法ではありません。たとえばQueryDict、クレイジーな理由でファイルに書き込みたい場合QueryDict.urlencode()は、その方法です。再構築するにQueryDictは、単に行いますQueryDict(urlencoded_data)


3
この方法は、不確定な動作の影響を受けます。特定のキーに1つ以上の値が含まれる場合、文字列を取得したり、文字列のリストを取得したりすることができます。
Asherah 2016年

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

6

値を配列にしたくない場合は、次の操作を実行できます。

# 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で詳細を確認できます。


2
私はこれがほぼ6歳であることを知っており、この答えに到達した人に指摘するだけです:Django> = 2.0(古いバージョンでも動作する可能性があります、それは私が使用しているものだけです)、あなたはQueryDict.dict()(つまりrequest.POST.dict())値を正しく返します。
Luca Bezerra、

伝説のルカ。これは私を一日中怒らせています!あなたの答えが私が仕事に就ける唯一の答えです。
scottapotamus

4

フォームの任意の値をシリアル化された値として保存したいのですが、同様の問題が発生しました。

私の答えは、辞書の内容を明示的に繰り返すことを避けます: 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

3

更新:

myDict = dict(queryDict._iterlists())

注:の_iterlistsメソッドではアンダースコアを使用してくださいqueryDict。Djangoバージョン:1.5.1


3

dict(request.POST) 配列でラップされた値を持つ奇妙なpython辞書を返します。

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

ここでas {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'}

Django> = 2.0(古いバージョンでも動作する可能性があります。これは私が使用しているものだけです)では、実行できQueryDict.dict()(つまりrequest.POST.dict())、値が正しく返されます。
Luca Bezerra、

2

追加するだけ

queryDict=dict(request.GET) または queryDict=dict(QueryDict)

ビューでは、データはpython DictとしてquerDictに保存されます。


1

これが私がその問題を解決した方法です:

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

1

私のように、あなたはおそらくDict()Pythonのメソッドに慣れているでしょう。ただし、これQueryDict()も簡単に使用できるオブジェクトです。たとえば、から値を取得したいとしますrequest.GET QueryDict()

これは次のように実行できますrequest.GET.__getitem__(<key>)

QueryDict()ドキュメント:https : //docs.djangoproject.com/en/2.0/ref/request-response/#django.http.QueryDict


1
二重下線メソッドの使用は避けてください。もっとpythonicな方法は、request.GET.get(<key>)or を使用することですrequest.GET.getlist(<key>)
Bobort

1

では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']

どちらが正しい。


0

私が試してみたの両方dict(request.POST)request.POST.dict()、あなたが持っている場合ことに気づいlist例えば値'var1':['value1', 'value2']あなたにネストさをrequest.POST、後の(request.POST.dict())のみ(前者は一方で、私は、ネストされたリスト内の最後の項目へのアクセスを与えたdict(request.POST))ネストされたリスト内のすべての項目にアクセスするために私を可能にしました。

これが誰かの役に立つことを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.