これは簡単な質問だと思います。小さな一歩が足りません。
(次のパラメーターの用語として)次の任意の数を実行したい:
[not signed in] -> profile -> login?next=/accounts/profile/ -> auth -> profile.
[not signed in] -> newsfeed -> login?next=/newsfeed/` -> auth -> newsfeed.
私が現在行っているのに対し:
[not signed in] -> profile -> login?next=/accounts/profile/ -> auth -> loggedin
[not signed in] -> newsfeed -> login?next=/newsfeed/ -> auth -> loggedin
どういうわけかnext
パラメータをlogin
のフォームからauth
に渡し、auth
にこのパラメータにリダイレクトさせたいと思っています。
現在、login.html
で試しています:
<input type='text' name="next" value="{{ next }}">
ただし、これは次の値を取得していません。デバッグツールバーから次のことがわかります。
GET data
Variable Value
u'next' [u'/accounts/profile/']
views
:
def auth_view(request):
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
print request.POST
return HttpResponseRedirect(request.POST.get('next'),'/accounts/loggedin')
else:
return HttpResponseRedirect('/accounts/invalid')
login.html
:
{% extends "base.html" %}
{% block content %}
{% if form.errors %}
<p class="error"> Sorry, you have entered an incorrect username or password</p>
{% endif %}
<form action="/accounts/auth/" method="post">{% csrf_token %}
<label for="username">User name:</label>
<input type="text" name="username" value="" id="username">
<label for="password">Password:</label>
<input type="password" name="password" value="" id="password">
<input type='text' name="next" value="{{ request.GET.next }}">
<input type="submit" value="login">
</form>
{% endblock %}
settings
:
from Django.conf.urls import patterns, include, url
from Django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
url(r'^admin/', include(admin.site.urls)),
('^accounts/', include('userprofile.urls')),
url(r'^accounts/login/$', 'Django_yunite.views.login'),
url(r'^accounts/auth/$', 'Django_yunite.views.auth_view'),
url(r'^accounts/logout/$', 'Django_yunite.views.logout'),
url(r'^accounts/loggedin/$', 'Django_yunite.views.loggedin'),
url(r'^accounts/invalid/$', 'Django_yunite.views.invalid_login'),
)
settings
:
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'Django.contrib.admin',
'Django.contrib.auth',
'Django.contrib.contenttypes',
'Django.contrib.sessions',
'Django.contrib.messages',
'Django.contrib.staticfiles',
'debug_toolbar',
'userprofile',
)
MIDDLEWARE_CLASSES = (
'Django.contrib.sessions.middleware.SessionMiddleware',
'Django.middleware.common.CommonMiddleware',
'Django.middleware.csrf.CsrfViewMiddleware',
'Django.contrib.auth.middleware.AuthenticationMiddleware',
'Django.contrib.messages.middleware.MessageMiddleware',
'Django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'Django_yunite.urls'
WSGI_APPLICATION = 'Django_yunite.wsgi.application'
# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/
LANGUAGE_CODE = 'en-ca'
TIME_ZONE = 'EST'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = (
('assets', '/home/user/GitHub/venv_yunite/Django_yunite/static/'),
)
TEMPLATE_DIRS = (
'./templates',
'/article/templates',
)
STATIC_ROOT = "/home/user/Documents/static/"
AUTH_PROFILE_MODULE = 'userprofile.UserProfile'
印刷ステートメントは空のu'next'
を示しています
クエリ文字列は、特別なコードを記述しなくても、暗黙的に任意のビューに渡されます。
next
キーが実際のログインフォーム(この場合、これは/accounts/login/
でレンダリングされるフォーム)から/accounts/auth
ビューに渡されることを確認するだけです。
これを行うには、設定でリクエストテンプレートコンテキストプロセッサ(Django.core.context_processors.request
)が有効になっていることを確認する必要があります。これを行うには、最初にTEMPLATE_CONTEXT_PROCESSORS
のデフォルト値をインポートしてから、次のようにsettings.py
にリクエストプロセッサを追加する必要があります。
from Django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
"Django.core.context_processors.request",
)
次に、次の形式で:
<form method="POST" action="/accounts/auth">
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.GET.next }}" />
{{ login_form }}
<input type="submit">
</form>
さて、あなたの/accounts/auth
ビューで:
def foo(request):
if request.method == 'POST':
# .. authenticate your user
# redirect to the value of next if it is entered, otherwise
# to /accounts/profile/
return redirect(request.POST.get('next','/accounts/profile/'))
あなたが探しているのは ログインデコレータ です。
あなたのviews.py
from Django.contrib.auth.decorators import login_required
@login_required(login_url="/accounts/login/")
def profile( request ):
"""your view code here"""
return HttpResponse("boo ya", "text/html")
次に、urls.pyに認証URLを追加します
(r'^accounts/login/$', 'Django.contrib.auth.views.login'),
最後に:インストールされているアプリにDjango.contrib.authがあり、AuthenticationMiddlewareがインストールされていることを確認してください。
settings.py
INSTALLED_APPS = (
-- snip --,
'Django.contrib.auth',
)
MIDDLEWARE_CLASSES = (
-- snip --,
'Django.contrib.auth.middleware.AuthenticationMiddleware',
)
あなたのtemplates/registerration/login.html
<form method="POST" action="/accounts/login/">
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}" />
{{ login_form }}
<input type="submit">
</form>
いつか同じような状況に直面しました。これを解決するために、私は自分のデコレータを作成しました-
def validate_request_for_login(f):
def wrap(request):
if not request.user.is_authenticated():
return redirect("/login?next=" + request.path)
return f(request)
return wrap
上記のデコレータはユーザー認証をチェックします。ユーザーが認証されていない場合は、リクエストオブジェクトからurl
を渡して、ユーザーをログインページにリダイレクトします。
私がやったことは次のとおりです。私には、これはちょっとしたハックの仕事のように思えます。 csrfでログインを使用するより良い方法はありますか?
views
:
def login(request):
c={}
c.update(csrf(request))
if 'next' in request.GET:
c['next'] = request.GET.get('next')
return render_to_response('login.html', c)
def auth_view(request):
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
if request.POST.get('next') != '':
return HttpResponseRedirect(request.POST.get('next'))
else:
return HttpResponseRedirect('/accounts/loggedin')
else:
return HttpResponseRedirect('/accounts/invalid')
login.html
:
<input type="hidden" name="next" value="{{ next }}"/>