Python 登录页面上的 POST 请求后在 Django 中生成的 MultiValueDictKeyError
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20736141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MultiValueDictKeyError generated in Django after POST request on login page
提问by PyUnchained
I'm trying to build a login page. I'm running Django 1.6.1. I've largely been following the tutorial at www.fir3net.com/Django/django.html. For convenience I will repost a lot of it here.
我正在尝试构建一个登录页面。我正在运行 Django 1.6.1。我一直在关注 www.fir3net.com/Django/django.html 上的教程。为方便起见,我将在此处重新发布很多内容。
Error Message:
错误信息:
Request Method: GET
Request URL: http://127.0.0.1:8000/login/
Database In Use: SQLite3
Django Version: 1.6.1
Python Version: 2.7.4
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.contenttypes',
'bookmarks')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickHymaning.XFrameOptionsMiddleware')
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
114. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/tatenda/Documents/Programming/Django/Progs/django_bookmarks/bookmarks/views.py" in login_user
17. username = request.POST['username']
File "/usr/local/lib/python2.7/dist-packages/django/utils/datastructures.py" in __getitem__
301. raise MultiValueDictKeyError(repr(key))
Exception Type: MultiValueDictKeyError at /login/
Exception Value: "'username'"
View Code (I understand that several of the import functions called here are superfluous to my immediate problem. Mostly they are redundant code from trying to follow previous tutorials on how to do this):
查看代码(我知道这里调用的几个导入函数对于我的直接问题来说是多余的。大多数情况下,它们是尝试遵循之前关于如何执行此操作的教程的冗余代码):
from django.http import*
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from django.template import Context
from django.template.loader import get_template
from django.http import HttpResponse, Http404
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.contrib.auth.decorators import login_required
def login_user(request):
username = password = ''
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password = password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect('/main_page/')
return render_to_response('base.html', context_instance = RequestContext(request))
@login_required(login_url = '/login/')
def main_page(request):
template = get_template('main_page.html')
variables = Context ({
'head_title':'Django Bookmarks',
'page_title':'Welcome to Django Bookmarks',
'page_body':'Where you store and share bookmarks!'
})
output = template.render(variables)
return HttpResponse(output)
def user_page(request, username):
try:
user = User.objects.get(username=username)
except:
raise Http404('Requested user not found.')
bookmarks = user.bookmark_set.all()
template = get_template('user_page.html')
variables = Context({
'username':username,
'bookmarks': bookmarks
})
output = template.render(variables)
return HttpResponse(output)
@csrf_exempt
def login_page(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request,user)
template = get_template('main_page.html')
variables = Context ({
'head_title':'Django Bookmarks',
'page_title':'Welcome to Django Bookmarks',
'page_body':'Where you store and share bookmarks!'
})
output = template.render(variables)
return HttpResponse(output)
else:
raise Http404('Disabled account, please contact administrator.')
else:
raise Http404('Invalid login.')
Info from urls.py file:
来自 urls.py 文件的信息:
from django.conf.urls import patterns, include, url
from django.contrib import admin
from bookmarks.views import*
admin.autodiscover()
urlpatterns = patterns('',
(r'^$', main_page),
(r'^user/(\w+)/$', user_page),
url(r'^login/$', login_user),
)
Base Template Used to Create Login Page (the file is named base.html):
Note- the CSS styling is bootstrap based
用于创建登录页面的基本模板(文件名为 base.html):
注意- CSS 样式是基于引导程序的
<!DOCTYPE html>
<html>
<head>
{% block head %}
<link rel = "stylesheet" href = "style.css" />
<title> {% block title %}{% endblock %} - My Webpage</title></div>
{% endblock %}
</head>
<body>
<div id = "content">{% block content %}{% endblock %}</div>
<div id = "footer">
{% block footer %}
© Copyright 2011 by <a href="http://domain.invalid/">you</a>
{% endblock %}
</div>
</body>
</html>
HTML Code for the Login Page (the file is named login.html):
登录页面的 HTML 代码(文件名为 login.html):
{% extends "base.html" %}
{% block main %}
<div id = "login">
<form class = "form-horizontal" name = "LoginForm" action = "/login/" method = "post">
{% csrf_token %}
{% if next %}
<input type = "hidden" name = "next" value = "{{ next }}" />
{% endif %}
<div class = "control-group">
<label class = "control-label" for = "username">Username</label>
<div class = "controls">
<input type = "text" id = "username" placeholder = "Username">
</div>
</div>
<div class = "control-group">
<label class = "control-label" for = "password">Password</label>
<div class = "controls">
<input type = "password" name = "password" id = "password" placeholder = "Password">
</div>
</div>
<div class = "control-group">
<div class = "controls">
<button type = "submit" class = "btn">Login</button>
</div>
</div>
</form>
</div>
{% endblock %}
采纳答案by Emack333
I had the same error, and i did this and it worked. Change:
我有同样的错误,我做了这个并且它起作用了。改变:
username = request.POST['username']
password = request.POST['password']
to:
到:
username = request.POST.get('username')
password = request.POST.get('password')
The above handles both the POST and GET methods that may result. I hope this helped.
以上处理可能产生的 POST 和 GET 方法。我希望这有帮助。
回答by Peter DeGlopper
When a request resolves to a view that's wrapped with the @login_requireddecorator, the request is redirected to the specified URL if the user is not logged in. So attempting to resolve your main_pageview while not logged in will cause the user's browser to issue a GETrequest to /login/. However, the view that handles that URL assumes a POSTrequest:
当请求解析为用@login_required装饰器包装的视图时,如果用户未登录,则请求将重定向到指定的 URL。因此,在未登录的情况下尝试解析您的main_page视图将导致用户的浏览器向 发出GET请求/login/。但是,处理该 URL 的视图假定一个POST请求:
username = request.POST['username']
password = request.POST['password']
The usual approach would be to follow the general pattern for using a form in a view: https://docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view
通常的方法是遵循在视图中使用表单的一般模式:https: //docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view
Specifically, check the request.methodattribute so you can behave appropriately on a GETrequest and render the form. Or use the built-in views, they're pretty easy to work with.
具体来说,检查request.method属性,以便您可以对GET请求采取适当的行为并呈现表单。或者使用内置的 views,它们很容易使用。
回答by MastermanSachin
I was able to suppress error by following @Emack333 but then, the code on views.py was not working and then upon close inspection, I've found that error was not on view file, rather it was on HTML side.
我能够通过遵循@Emack333 来抑制错误,但是,views.py 上的代码不起作用,然后经过仔细检查,我发现错误不在视图文件中,而是在 HTML 端。
This error got generated because there was a mismatch of name attribute on the HTML input tag and in your case, it was name attr is missing.
生成此错误是因为 HTML 输入标记上的 name 属性不匹配,在您的情况下,缺少 name attr。
<input type = "text" id = "username" placeholder = "Username" name="username">
回答by Alexander Moy
The real issue is the forms within your template.
真正的问题是模板中的表单。
You need to use the name=attribute to assign the name of the key instead of the id=attribute.
您需要使用name=属性来分配键的名称而不是id=属性。
I just solved this for my own project and realized this was the culprit.
我刚刚为我自己的项目解决了这个问题,并意识到这是罪魁祸首。

