我正在尝试构建一个登录页面。我正在运行Django 1.6.1。我在很大程度上遵循了www.fir3net.com/Django/django.html上的教程。为方便起见,我会在这里重新发布很多内容。
错误讯息:
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.clickjacking.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'"
查看代码(我知道这里调用的几个导入函数对我当前的问题是多余的。大多数情况下,它们都是冗余代码,因为我们试图按照之前的教程来解决这个问题):
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.')
来自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.html):
注意 - CSS样式是基于bootstrap的
<!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代码(该文件名为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 %}
答案 0 :(得分:19)
我遇到了同样的错误,我做了这个并且有效。 变化:
username = request.POST['username']
password = request.POST['password']
为:
username = request.POST.get('username')
password = request.POST.get('password')
以上处理可能导致的POST和GET方法。 我希望这会有所帮助。
答案 1 :(得分:2)
当请求解析为包含@login_required
装饰器的视图时,如果用户未登录,请求将重定向到指定的URL。因此,尝试解析main_page
视图登录后,用户的浏览器会向GET
发出/login/
请求。但是,处理该URL的视图假定POST
请求:
username = request.POST['username']
password = request.POST['password']
通常的做法是遵循在视图中使用表单的一般模式: https://docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view
具体来说,请检查request.method
属性,以便您可以对GET
请求采取适当的行为并呈现表单。或者使用built-in views,它们很容易使用。
答案 2 :(得分:0)
我可以通过遵循@ Emack333来抑制错误,但是,views.py上的代码无法正常工作,然后经过仔细检查,我发现错误不在视图文件上,而是在HTML方面。
之所以产生此错误,是因为HTML输入标签上的name属性不匹配,在您的情况下,这是缺少name attr。
<input type = "text" id = "username" placeholder = "Username" name="username">
答案 3 :(得分:0)
真正的问题是模板中的表单。
您需要使用'name ='属性而不是'id ='属性来分配密钥名称。
我刚刚为自己的项目解决了这个问题,并意识到这是罪魁祸首。