django MultiValueDictKeyError 오류, 어떻게 처리합니까


174

데이터베이스에 객체를 저장하려고하는데 MultiValueDictKeyError오류가 발생합니다.

문제는 양식 내에 있으며, is_private확인란으로 표시됩니다. 확인란을 선택하지 않으면 아무 것도 전달되지 않습니다. 오류가 발생하는 곳입니다.

이 예외를 올바르게 처리하고 포착하려면 어떻게해야합니까?

라인은

is_private = request.POST['is_private']

1
우리에게 전체 오류와 흔적을 보여주는 것이 좋습니다. 또한 오류가 발생한 코드 부분을 더 많이 보여주십시오.
rzetterberg

1
django rest에서 다른 Modelviewset을 사용할 때이 오류를 보았습니다 .....
Amrit

1
단순히 'is_private'키가 존재하지 않음을 의미합니다!
ThePhi

답변:


281

MultiValueDict의 get방법을 사용하십시오 . 이것은 또한 표준 dicts에 존재하며 존재하지 않는 경우 기본값을 제공하면서 값을 가져 오는 방법입니다.

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

일반적으로,

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

2
이것은 나에게 None 값을 제공하지만 POST에 값을 보내고 있습니다 : /
Jesus Almaral-Hackaprende

올바른 동작입니다. 확인란을 선택 checked하면 전송되지만 null선택하지 않으면 전송 됩니다. Chrome / Firefox DEV 도구의 "네트워크"패널에서이를 확인할 수 있습니다. 그렇기 때문에 False기본값으로 설정 null해야합니다 false.
WesternGun

78

가장 적합한 것을 선택하십시오 :

1

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

경우 is_private키 request.POST에 존재하는 is_private변수는 그와 동일 할 것이다 아니라면, 이는 거짓으로 동일 할 것이다.

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 번을 추천 할 수는 없습니다.
Joe

6
예외 시스템을 남용하는 것처럼 보입니다. 예외적 인 동작 (예 : 발생할 수 있고 처리해야하지만 정상적인 프로그램 흐름에서는 예상하지 않는 동작)을 처리하는 경우는 예외입니다. 이 경우 예외가 발생하여 가능한 프로그램 흐름의 50 %에서 잡 힙니다. 여기에 속도 저하가 추가됩니다. 파이썬에서 어떻게 작동하는지에 대한 세부 사항을 모르지만 비싼 스택 추적이 포함될 것이라고 생각합니다.
Joe

13
django.utils.datastructures에서 가져 오기 MultiValueDictKeyError
Akseli Palén

8
@Joe-파이썬에서이 접근법은 꽤 일반적입니다. 예외를 잡으면 스택 추적이 자동으로 생성되지 않습니다. docs.python.org/2/glossary.html#term-eafp
bjudson

9
3 단계에는 아무 문제가 없습니다. EAFP (권한보다 용서 요청)가 더 쉬우 며, 파이썬에서 가장 권장되는 코딩 스타일입니다. StackOverflow에 대한 많은 게시물이 이것에 대해서도 논의했습니다.
Bobort

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

기억해야 할 또 다른 사항 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는 모든 요청 매개 변수를 포함하는 사전과 유사한 객체입니다. 이것은 장고에만 해당됩니다.

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에서 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에 대해 다른보기 함수를 잘못 호출하여 실수를 저지를 수 있습니다.

이것이 초보자 프로그래머가 장고에 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.