web-dev-qa-db-ja.com

Django after POSTログインページのリクエストで生成されたMultiValueDictKeyError

ログインページを作成しようとしています。私は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 %}
                &copy; 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 %}
7
PyUnchained

私は同じエラーを抱えていました、そして私はこれをしました、そしてそれは働きました。変化する:

username = request.POST['username']
password = request.POST['password'] 

に:

username = request.POST.get('username')
password = request.POST.get('password')

上記は、結果として生じる可能性のあるPOSTメソッドとGETメソッドの両方を処理します。これがお役に立てば幸いです。

23
Emack333

リクエストが@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 -表示

具体的には、request.method属性を確認して、GETリクエストで適切に動作し、フォームをレンダリングできるようにします。または、 組み込みビュー を使用すると、操作が非常に簡単になります。

2
Peter DeGlopper

@ Emack333をフォローすることでエラーを抑えることができましたが、views.pyのコードが機能せず、詳しく調べてみると、エラーはビューファイルではなく、HTML側にあることがわかりました。

このエラーは、HTML入力タグにname属性の不一致があり、あなたの場合、nameattrが欠落しているために生成されました。

<input type = "text" id = "username" placeholder = "Username" name="username">
1
MastermanSachin

本当の問題は、テンプレート内のフォームです。

'id ='属性の代わりに、 'name ='属性を使用してキーの名前を割り当てる必要があります。

私は自分のプロジェクトでこれを解決し、これが原因であることに気づきました。

0
Alexander Moy