django MultiValueDictKeyError错误,我该如何处理它

dot*_*tty 153 python django exception

我正在尝试将对象保存到我的数据库,但它会抛出MultiValueDictKeyError错误.

问题在于表单,is_private由复选框表示.如果未选中该复选框,则显然不会传递任何内容.这是错误被丢失的地方.

我如何正确处理这个异常,并抓住它?

这条线是

is_private = request.POST['is_private']
Run Code Online (Sandbox Code Playgroud)

ada*_*ish 255

使用MultiValueDict的get方法.这也出现在标准dicts上,如果不存在,则提供默认值时提取值.

is_private = request.POST.get('is_private', False)
Run Code Online (Sandbox Code Playgroud)

通常,

my_var = dict.get(<key>, <default>)
Run Code Online (Sandbox Code Playgroud)

  • 这给了我一个 None 值,但我在 POST 上发送值:/ (3认同)
  • 这是正确的行为.. 复选框在选中时发送“checked”,但如果未选中则发送“null”。您可以在 Chrome/Firefox DEV 工具的“网络”面板中检查这一点。这就是为什么您将“False”设置为默认值:如果得到“null”,则将其设为“false”。 (2认同)

Sil*_*ght 73

选择最适合您的方法:

1

is_private = request.POST.get('is_private', False);
Run Code Online (Sandbox Code Playgroud)

如果is_privaterequest.POST中存在key,则is_private变量将等于它,否则,它将等于False.

2

if 'is_private' in request.POST:
    is_private = request.POST['is_private']
else:
    is_private = False
Run Code Online (Sandbox Code Playgroud)

3

from django.utils.datastructures import MultiValueDictKeyError
try:
    is_private = request.POST['is_private']
except MultiValueDictKeyError:
    is_private = False
Run Code Online (Sandbox Code Playgroud)

  • 真的不能推荐3号. (12认同)
  • 来自django.utils.datastructures导入MultiValueDictKeyError (11认同)
  • @Joe - 在Python中,这种方法很常见.如果您正在捕获异常,它将不会自动生成堆栈跟踪.http://docs.python.org/2/glossary.html#term-eafp (8认同)
  • 第3步没有任何问题.我们称Easient要求宽恕而非许可(EAFP),并且它是Python中强烈推荐的编码风格.StackOverflow上的大量帖子甚至讨论过这个问题. (8认同)
  • 这似乎是滥用例外系统.例外情况应该是处理异常行为(即您知道可能发生的行为,必须处理,但您在正常的程序流程中没有预料到).在这种情况下,将抛出异常并将其捕获到50%的可能程序流中.除此之外还有减速.我不知道它在Python中如何工作的细节,但我想会涉及到昂贵的堆栈跟踪. (6认同)
  • @bjudson我知道,异常用于各种各样的事情,并非所有这些都是语言设计者的意图.举例来说,由"java.io.EOFException"引起的愤怒,对此有很多不同意见.我不建议使用try/catch进行非异常控制流程,即使它有效,因为它不是如何设计检查异常的.我接受这是一种意见而不是事实. (2认同)

Joe*_*Joe 10

你得到了,因为当你不在那里时,你正试图从字典中获取一个密钥.你需要先测试它是否在那里.

尝试:

is_private = 'is_private' in request.POST
Run Code Online (Sandbox Code Playgroud)

要么

is_private = 'is_private' in request.POST and request.POST['is_private']
Run Code Online (Sandbox Code Playgroud)

取决于您使用的值.


Leo*_*Leo 7

要记住的另一件事是request.POST['keyword']指由指定的 htmlname属性标识的元素keyword

所以,如果你的表格是:

<form action="/login/" method="POST">
  <input type="text" name="keyword" placeholder="Search query">
  <input type="number" name="results" placeholder="Number of results">
</form>
Run Code Online (Sandbox Code Playgroud)

然后,request.POST['keyword']request.POST['results']将分别包含输入元素keyword和的值results


小智 5

你为什么不尝试is_private在你的模型中定义default=False

class Foo(models.Models):
    is_private = models.BooleanField(default=False)
Run Code Online (Sandbox Code Playgroud)

  • 那不能防止他通过手工检查POST的值而得到的错误。 (2认同)

TNT*_*TNT 5

对于我来说,这个错误发生在我的 django 项目中,原因如下:

  1. 我在项目的模板文件夹中的 home.html 中插入了一个新的超链接,如下所示:

    <input type="button" value="About" onclick="location.href='{% url 'about' %}'">
    Run Code Online (Sandbox Code Playgroud)

  2. 在views.py中,我对count和about有以下定义:

   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")
Run Code Online (Sandbox Code Playgroud)
  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"),
    ]
Run Code Online (Sandbox Code Playgroud)

正如在没有中可以看到的。上面的 3,在最后一个 url 模式中,我错误地调用了views.count,而我需要调用views.about。fulltext = request.GET['fulltext']views.py 的 count 函数(由于 urlpatterns 中的错误输入而被错误调用)中的这一行抛出了 multivaluedictkeyerror 异常。

然后我将 urls.py 中的最后一个 url 模式更改为正确的 ie path('about/',views.about,name="about"),一切正常。

显然,一般来说,django 的新手程序员可能会犯我所犯的错误,错误地为 url 调用另一个视图函数,该函数可能期望不同的参数集或在其渲染调用中传递不同的对象集,而不是预期的行为。

希望这对 django 新手程序员有所帮助。