django MultiValueDictKeyError错误,我该如何处理


174

我正在尝试将对象保存到数据库中,但是它引发了MultiValueDictKeyError错误。

问题出在表格内,is_private用一个复选框表示。如果未选中该复选框,则显然不会传递任何内容。这是消除错误的地方。

我如何正确处理并捕获此异常?

该行是

is_private = request.POST['is_private']

1
一个好主意是向我们展示整个错误和跟踪。还要向我们展示引发错误的那部分代码。
rzetterberg

1
谁能解释为什么会发生此错误?当我在django rest中使用不同的Modelviewset时,我已经看到此错误....
Amrit

1
它的意思很简单:键“ is_private”不存在!
ThePhi

Answers:


281

使用MultiValueDict的get方法。这在标准字典中也存在,并且是一种在不存在默认值的情况下获取值的方法。

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

通常,

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

2
这给了我None值,但是我在POST上发送了值:/
Jesus Almaral-Hackaprende 17-10-26

这是正确的行为。复选框checked在选中时发送,但null在未选中时发送。您可以在Chrome / Firefox DEV工具的“网络”面板中进行检查。这就是为什么你设置False为默认值:如果有null,使它false
WesternGun

78

选择最适合您的:

1个

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

如果is_privatekey在request.POST中存在,则is_private变量等于它,如果不相等,则它等于False。

2

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

3

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én13年

8
@Joe-在Python中,这种方法非常普遍。如果您正在捕获异常,它将不会自动生成堆栈跟踪。docs.python.org/2/glossary.html#term-eafp
bjudson

9
第3步没有错。我们称其为宽恕而不是许可(EAFP),这是Python中强烈推荐的编码样式。StackOverflow上的许多帖子甚至对此进行了讨论。
Bobort

12

之所以会这样,是因为您试图从不存在的字典中获取密钥。您需要先测试它是否在其中。

尝试:

is_private = 'is_private' in request.POST

要么

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

取决于您使用的值。



4

要记住的另一件事是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']包含输入元素keyword和的值results


1

首先检查请求对象是否具有'is_private'键参数。多数情况下,此MultiValueDictKeyError发生是因为类字典的请求对象中缺少键。由于字典是无序键,因此值对为“关联存储器”或“关联数组”

换句话说。request.GET或request.POST是类似于字典的对象,包含所有请求参数。这是特定于Django的。

如果key在字典中,则方法get()返回给定key的值。如果key不可用,则返回默认值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中,我具有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")
  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.about。fulltext = request.GET['fulltext']views.py的count函数中的这一行(由于在urlpatterns中输入错误而被错误地调用)引发了multivaluedictkeyerror异常。

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

显然,通常django中的新手程序员会犯这样的错误,即我错误地为URL调用了另一个视图函数,这可能是期望使用不同的参数集或在其render调用中传递不同的对象集,而不是预期的行为。

希望这可以帮助一些新手程序员使用django。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.