django MultiValueDictKeyError ошибка, как мне с ней справиться

174

Я пытаюсь сохранить объект в моей базе данных, но выдает MultiValueDictKeyErrorошибку.

Проблемы лежат в форме, is_privateкоторая представлена ​​флажком. Если флажок НЕ установлен, очевидно, ничего не пропущено. Это где ошибка забрасывается.

Как правильно разобраться с этим исключением и поймать его?

Линия

is_private = request.POST['is_private']
рехнувшийся
источник
1
Хорошей идеей было бы показать нам всю ошибку и след. Также покажите нам больше той части кода, где возникает ошибка.
rzetterberg
1
Может кто-нибудь объяснить, почему возникает эта ошибка? Я видел эту ошибку, когда я использую другой Modelviewset в django rest .....
Amrit
1
это означает просто: ключ is_private не существует!
ThePhi

Ответы:

282

Используйте метод MultiValueDict get. Это также присутствует в стандартных диктовках и является способом извлечения значения при обеспечении значения по умолчанию, если оно не существует.

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

В общем-то,

my_var = dict.get(<key>, <default>)
adamnfish
источник
2
Это дает мне значение None, но я отправляю значение на POST: /
Иисус Алмарал - Hackaprende
Это правильное поведение. Флажок отправлять, checkedкогда установлен флажок, но будет отправлять, nullесли флажок не установлен. Вы можете проверить это на панели «Сеть» инструмента DEV Chrome / Firefox. Вот почему вы устанавливаете Falseзначение по умолчанию: если есть null, сделайте это false.
WesternGun
78

Выберите, что лучше для вас:

1

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

Если is_privateключ присутствует в 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 import MultiValueDictKeyError
Аксели Пален,
8
@Joe - В Python такой подход довольно распространен. Если вы ловите исключение, оно не будет автоматически генерировать трассировку стека. docs.python.org/2/glossary.html#term-eafp
bjudson
9
В шаге 3 нет ничего плохого. Мы называем, что Проще просить прощения, чем разрешения (EAFP), и это очень рекомендуемый стиль кодирования в Python. Множество постов на StackOverflow даже обсуждали это.
Боборт
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 вручную для значения.
Аполлон Данных
4

Также следует помнить, что это request.POST['keyword']относится к элементу, идентифицированному указанным nameатрибутом html 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 - это словарь-объект, содержащий все параметры запроса. Это специфично для Джанго.

Метод get () возвращает значение для данного ключа, если ключ находится в словаре. Если ключ недоступен, возвращается значение по умолчанию Нет.

Вы можете обработать эту ошибку, поместив:

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'] в функции count (которая была вызвана по ошибке из-за неправильной записи в urlpatterns) для views.py вызвала исключение multivaluedictkeyerror.

Затем я изменил последний шаблон URL в urls.py на правильный, т.е. path('about/',views.about,name="about") И все работало нормально.

По-видимому, в общем, программист-новичок в django может совершить ошибку, которую я допустил, ошибочно вызвав другую функцию представления для URL-адреса, которая может ожидать другой набор параметров или передачу другого набора объектов при вызове рендеринга, а не предполагаемое поведение.

Надеюсь, это поможет начинающему программисту в Django.

тротил
источник