Django之后@login_required重定向到下一个 [英] Django after @login_required redirect to next
问题描述
我想要执行以下任意数量(作为下一个参数中的术语):
[未登录] - >个人资料 - > login?next = / accounts / profile / - > auth - >个人资料。
[未登录] - > newsfeed - > login?next = / newsfeed /` - > auth - >新闻源。
而我目前正在进行:
[未登录] - >个人资料 - > login?next = / accounts / profile / - > auth - >登录
[未登录] - > newsfeed - >登录?next = / newsfeed / - > auth - >登录
我希望以某种方式通过 next
参数从登录表单
到 auth
并且具有 auth
重定向到此参数
目前我正在尝试我的 login.html
:
< input type ='text'name =nextvalue ={{next}}>
但是这没有得到下一个值。我可以从调试工具栏中看到:
GET数据
变量值
u'next'[你/帐户/个人资料/']
views
:
def auth_view(request):
username = request.POST.get('username',' ')
password = request.POST.get('password','')
user = auth.authenticate(username = username,password = password)
如果用户是不是没有:
auth.login(请求,用户)
打印请求.POST
返回HttpResponseRedirect(request.POST.get('next'),'/ accounts / loggedin')
else:
return HttpResponseRedirect('/ accounts / invalid')
login.html
:
{%extendsbase.html%}
{%block content%}
{%if form.errors%}
< p class =error>对不起,您输入的用户名或密码不正确< / p>
{%endif%}
< form action =/ accounts / auth /method =post> {%csrf_token%}
< label for =username> ;用户名:< / label>
< input type =textname =usernamevalue =id =username>
< label for =password>密码:< / label>
< input type =passwordname =passwordvalue =id =password>
< input type ='text'name =nextvalue ={{request.GET.next}}>
< input type =submitvalue =login>
< / form>
{%endblock%}
/ code>:
from django.conf.urls import patterns,include,url
从django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
#示例:
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'),
)
设置
:
#在项目中构建路径,如下所示:os.path.join(BASE_DIR,...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__ file__))
#安全警告:在生产中不要运行调试打开!
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
#应用程序定义
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 .crfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware'
)
ROOT_URLCONF ='django_yunite.urls'
WSGI_APPLICATION ='django_yunite.wsgi.a pplication'
#国际化
#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
#静态文件(CSS,JavaScript,图像)
#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'
查询字符串被隐式传递给任何视图,而不需要写任何特殊的
所有你需要做的是确保下一个
键是从实际的登录表单(在你的情况下,这是在 / accounts / login /
中呈现的表单,到 / accounts / auth
为了做到这一点,你需要确保你有请求模板上下文处理器( django.core.context_processors.request
)。为此,首先需要导入 TEMPLATE_CONTEXT_PROCESSORS
的默认值,然后在 settings.py $ c中添加请求处理器$ c>,像这样:
from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS +(
django.core.context_processors.request,
)
然后以以下形式:
< form method =POSTaction =/ accounts / auth>
{%csrf_token%}
< input type =hiddenname =nextvalue ={{request.GET.next}}/>
{{login_form}}
< input type =submit>
< / form>
现在,在您的 / accounts / auth
查看:
def foo(request):
if request.method =='POST':
#..验证您的用户
#重定向到下一个的值,如果输入,否则
#到/ accounts / profile /
返回重定向.POST.get('next','/ accounts / profile /'))
I feel like this is an easy question and I'm just missing 1 small step.
I want to do any number of the following (as the term in the next parameter):
[not signed in] -> profile -> login?next=/accounts/profile/ -> auth -> profile.
[not signed in] -> newsfeed -> login?next=/newsfeed/` -> auth -> newsfeed.
Whereas I am currently going:
[not signed in] -> profile -> login?next=/accounts/profile/ -> auth -> loggedin
[not signed in] -> newsfeed -> login?next=/newsfeed/ -> auth -> loggedin
I am looking to somehow pass the next
parameter from a form on login
to auth
and have auth
redirect to this parameter
Currently I am trying in my login.html
:
<input type='text' name="next" value="{{ next }}">
however this is not getting the next value. I can see from the debug tool bar:
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'
the print statment shows an empty u'next'
The query string is implicitly passed to any view, without you having to write any special code.
All you have to do is make sure that the next
key is passed from the actual login form (in your case, this is the form that is rendered in /accounts/login/
), to the /accounts/auth
view.
To do that, you need to make sure you have the request template context processor (django.core.context_processors.request
) enabled in your settings. To do this, first you need to import the default value for TEMPLATE_CONTEXT_PROCESSORS
, then add the request processor to it in your settings.py
, like this:
from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
"django.core.context_processors.request",
)
Then in the form:
<form method="POST" action="/accounts/auth">
{% csrf_token %}
<input type="hidden" name="next" value="{{ request.GET.next }}" />
{{ login_form }}
<input type="submit">
</form>
Now, in your /accounts/auth
view:
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/'))
这篇关于Django之后@login_required重定向到下一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!