django MultiValueDictKeyError помилка, як мені з цим боротися


174

Я намагаюся зберегти об’єкт у своїй базі даних, але це видає MultiValueDictKeyErrorпомилку.

Проблеми полягають у формі, is_privateзнак представлений прапором. Якщо прапорець НЕ встановлений, явно нічого не проходить. Тут відбувається помилка.

Як я правильно поводжусь із цим винятком і зловити його?

Лінія є

is_private = request.POST['is_private']

1
Хорошою ідеєю було б показати нам всю помилку та слід. Також покажіть нам більше тієї частини коду, де підвищена помилка.
rzetterberg

1
Хто-небудь може пояснити, чому виникає ця помилка? Я бачив цю помилку, коли я використовую інший Modelviewset у режимі відпочинку з джанго .....
Amrit

1
це означає просто: ключ "is_private" не існує!
ThePhi

Відповіді:


281

Використовуйте getметод MultiValueDict . Це також є в стандартних диктатах і є способом отримати значення, надаючи значення за замовчуванням, якщо воно не існує.

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

78

Виберіть найкраще для вас:

1

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

Якщо is_privateв запиті присутній ключ.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
Akseli Palén

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 () повертає значення для даного ключа, якщо ключ є у словнику. Якщо ключ недоступний, тоді повертається значення за замовчуванням None.

Ви можете вирішити цю помилку, поставивши:

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

1

Для мене ця помилка сталася в моєму проекті джанго через наступне:

  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.about. Ця fulltext = request.GET['fulltext']функція підрахунку рядка (яку помилково називали через неправильний запис у URL-адреси) views.py викинула багатозначне виняток помилки.

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

Мабуть, в цілому новачок-програміст у django може зробити помилку, яку я зробив помилково, викликаючи іншу функцію перегляду для URL-адреси, яка може очікувати різного набору параметрів або передавання різного набору об'єктів у своєму виклику візуалізації, а не передбачуваної поведінки.

Сподіваюся, це допоможе програмісту-початківцю на джанго.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.