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.
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.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'"
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:
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
<!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):
{% 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 %}
To fix the Python Django MultiValueDictKeyError error, we use the dictionary get method to get the dict value and return a default if the dict key doesn't exist. to call get on request. POST to get the is_private dict value from the POST request payload. And if is_private wasn't sent, then we return False .
This is specific to Django. The method get() returns a value for the given key if key is in the dictionary. If key is not available then returns default value None. You can handle this error by putting : is_private = request.POST.get('is_private', False);
When a POST request is received at the Django server, the data in the request can be retrieved using the HTTPRequest. POST dictionary. All the data of the POST request body is stored in this dictionary. For example, you can use the following code snippet inside your view.py file.
_ in Django is a convention that is used for localizing texts. It is an alias for ugettext_lazy.
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.
When a request resolves to a view that's wrapped with the @login_required
decorator, the request is redirected to the specified URL if the user is not logged in. So attempting to resolve your main_page
view while not logged in will cause the user's browser to issue a GET
request to /login/
. However, the view that handles that URL assumes a POST
request:
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
Specifically, check the request.method
attribute so you can behave appropriately on a GET
request and render the form. Or use the built-in views, they're pretty easy to work with.
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.
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.
<input type = "text" id = "username" placeholder = "Username" name="username">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With