django MultiValueDictKeyErrorエラー、どう対処するか


174

オブジェクトをデータベースに保存しようとしていますが、MultiValueDictKeyErrorエラーが発生します。

問題はフォーム内にありis_private、チェックボックスで表されます。チェックボックスが選択されていない場合、明らかに何も渡されません。ここでエラーが発生します。

この例外を適切に処理してキャッチするにはどうすればよいですか?

ラインは

is_private = request.POST['is_private']

1
エラーとトレース全体を表示することをお勧めします。また、エラーが発生したコード部分の詳細を示します。
rzetterberg、

1
誰もがこのエラーが発生する理由を説明できますか?私はdjango rest .....で別のModelviewsetを使用すると、このエラーを見ました
Amrit

1
それは単に意味します:キー 'is_private'は存在しません!
ThePhi 2017

回答:


281

MultiValueDictのgetメソッドを使用します。これは標準の辞書にもあり、値が存在しない場合にデフォルトを提供しながら値をフェッチする方法です。

is_private = request.POST.get('is_private', False)

一般的に、

my_var = dict.get(<key>, <default>)

2
これにより、None値が得られますが、POSTで値を送信しています:/
イエスアルマラル-Hackaprende

これは正しい動作です。チェックボックスがオンのchecked場合は送信されますが、オフのnull場合は送信されます。これは、Chrome / Firefox DEVツールの[ネットワーク]パネルで確認できます。そのためFalse、デフォルト値として設定します。取得した場合はnull、それを作成しfalseます。
WesternGun 2018年

78

あなたに最適なものを選択してください:

1

is_private = request.POST.get('is_private', False);

is_privaterequest.POSTにキーが存在する場合、is_private変数はそれに等しくなります。そうでない場合、Falseに等しくなります。

2

if 'is_private' in request.POST:
    is_private = request.POST['is_private']
else:
    is_private = False

from django.utils.datastructures import MultiValueDictKeyError
try:
    is_private = request.POST['is_private']
except MultiValueDictKeyError:
    is_private = False

12
本当に番号3.お勧めすることはできません
ジョー

6
例外システムの乱用のようです。例外は、例外的な動作(つまり、発生する可能性があり、対処する必要があるが、通常のプログラムフローでは予期しない動作)を処理するためのものです。この場合、例外がスローされ、可能なプログラムフローの50%でキャッチされます。それに加えて、スローダウンです。Pythonでどのように機能するか詳細はわかりませんが、高価なスタックトレースが含まれると思います。
ジョー

13
django.utils.datastructuresからインポートMultiValueDictKeyError
AkseliPalénFeb

8
@Joe-Pythonでは、このアプローチはかなり一般的です。例外をキャッチしている場合、スタックトレースは自動的には生成されません。docs.python.org/2/glossary.html#term-eafp
bjudson

9
手順3には何も問題はありません。許可よりも許しを求める方が簡単(EAFP)であり、Pythonで強く推奨されているコーディングスタイルです。StackOverflowに関する多くの投稿でこれについても議論されています。
Bobort 2017

12

あなたはそれがそこにないときに辞書からキーを取得しようとしているのでそれを得る。最初にそこにあるかどうかをテストする必要があります。

試してください:

is_private = 'is_private' in request.POST

または

is_private = 'is_private' in request.POST and request.POST['is_private']

使用している値に応じて。


5

is_privateモデルで次のように定義しようとしないのはなぜdefault=Falseですか?

class Foo(models.Models):
    is_private = models.BooleanField(default=False)

2
それでも、POSTで値を手動でチェックしているエラーを防ぐことはできません。
Apollo Data

4

もう1つ覚えておかなければならないのはrequest.POST['keyword']、指定されたhtml name属性によって識別される要素を参照することですkeyword

したがって、フォームが次の場合:

<form action="/login/" method="POST">
  <input type="text" name="keyword" placeholder="Search query">
  <input type="number" name="results" placeholder="Number of results">
</form>

次いで、request.POST['keyword']及びrequest.POST['results']入力要素の値を含むであろうkeywordresults、それぞれ。


1

まず、リクエストオブジェクトに「is_private」キーパラメータがあるかどうかを確認します。ほとんどの場合、このMultiValueDictKeyErrorは、ディクショナリのようなリクエストオブジェクトにキーがないために発生しました。辞書は順不同のキーなので、値のペアは「連想記憶」または「連想配列」

言い換えれば。request.GETまたはrequest.POSTは、すべての要求パラメーターを含む辞書のようなオブジェクトです。これはDjangoに固有です。

get()メソッドは、キーが辞書にある場合、指定されたキーの値を返します。キーが使用できない場合、デフォルト値のNoneを返します。

このエラーは次のように入力して処理できます。

is_private = request.POST.get('is_private', False);

1

私にとって、このエラーは次の理由で私のdjangoプロジェクトで発生しました:

  1. 次のように、プロジェクトのテンプレートフォルダーにあるhome.htmlに新しいハイパーリンクを挿入しました。

    <input type="button" value="About" onclick="location.href='{% url 'about' %}'">

  2. views.pyでは、カウントと約について次の定義がありました。

   def count(request):
           fulltext = request.GET['fulltext']
           wordlist = fulltext.split()
           worddict = {}
           for word in wordlist:
               if word in worddict:
                   worddict[word] += 1
               else:
                   worddict[word] = 1
                   worddict = sorted(worddict.items(), key = operator.itemgetter(1),reverse=True)
           return render(request,'count.html', 'fulltext':fulltext,'count':len(wordlist),'worddict'::worddict})

   def about(request): 
       return render(request,"about.html")
  1. urls.pyには、次のURLパターンがありました。
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('',views.homepage,name="home"),
        path('eggs',views.eggs),
        path('count/',views.count,name="count"),
        path('about/',views.count,name="about"),
    ]

いいえで見ることができるように。上記の3、最後のURLパターンでは、views.countを呼び出す必要があったのに対し、views.countを誤って呼び出していました。fulltext = request.GET['fulltext']views.pyのcount関数のこの行(urlpatternのエントリが誤っているために誤って呼び出された)は、multivaluedictkeyerror例外をスローしました。

次に、urls.pyの最後のURLパターンを正しいものに変更しましたpath('about/',views.about,name="about")。つまり、すべて正常に動作しました。

どうやら、一般的に、djangoの初心者プログラマーは、URLの別のビュー関数を誤って呼び出すことで犯した間違いを犯す可能性があります。これは、意図した動作ではなく、異なるパラメーターのセットを期待するか、レンダーコールで異なるオブジェクトのセットを渡す可能性があります。

これが初心者プログラマーのdjangoに役立つことを願って

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