Django redirect после входа в систему не работает "далее" не публикуется? [дубликат]
этот вопрос уже есть ответ здесь:
у меня есть страница входа в систему, которая работает нормально, за исключением редиректа на страницу реферера. Пользователь получает электронное письмо с прямой ссылкой в приложении, они (в этот пример) еще не вошли в систему и перенаправляются на страницу входа в систему. После успешного входа пользователь перенаправляется на жестко закодированный путь. См. пример ниже.
URL в электронной почте:http://localhost:8000/issueapp/1628/view/22
URL страницы входа в систему: http://localhost:8000/login?next=/issueapp/1628/view/22
просмотр входа (с жестко закодированным перенаправлением):
def login_user(request):
state = "Please log in below..."
username = password = ''
if request.POST:
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)
state = "You're successfully logged in!"
return HttpResponseRedirect('/issueapp/1628/')
else:
state = "Your account is not active, please contact the site admin."
else:
state = "Your username and/or password were incorrect."
return render_to_response(
'account_login.html',
{
'state':state,
'username': username
},
context_instance=RequestContext(request)
)
вид входа в систему (с перенаправлением" next"):
def login_user(request):
state = "Please log in below..."
username = password = ''
if request.POST:
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)
state = "You're successfully logged in!"
return HttpResponseRedirect(request.GET['next'])
else:
state = "Your account is not active, please contact the site admin."
else:
state = "Your username and/or password were incorrect."
return render_to_response(
'account_login.html',
{
'state':state,
'username': username
},
context_instance=RequestContext(request)
)
вышеуказанное представление приводит к исключению "Key 'next' not found in <QueryDict: {}>"
в форме не отображается сообщение " далее" переменная, хотя она есть в url и в форме.
Я искал и искал везде и не могу понять, почему это не работает. Есть идеи?
дополнительная ссылка:
шаблон входа в систему:
{% block content %}
{{ state }}
<form action="/login/" method="post" >
{% csrf_token %}
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% endif %}
username:
<input type="text" name="username" value="{{ username }}" /><br />
password:
<input type="password" name="password" value="" /><br />
<input type="submit" value="Log In"/>
{% debug %}
</form>
{% endblock %}
EDIT: ниже приведен код, который теперь работает для меня (благодаря помощи Paulo Bu)! **
Посмотреть Логин:
def login_user(request):
state = "Please log in below..."
username = password = ''
next = ""
if request.GET:
next = request.GET['next']
if request.POST:
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)
state = "You're successfully logged in!"
if next == "":
return HttpResponseRedirect('/issueapp/')
else:
return HttpResponseRedirect(next)
else:
state = "Your account is not active, please contact the site admin."
else:
state = "Your username and/or password were incorrect."
return render_to_response(
'account_login.html',
{
'state':state,
'username': username,
'next':next,
},
context_instance=RequestContext(request)
)
Шаблон Входа В Систему:
{{ state }}
{% if next %}
<form action="/login/?next={{next}}" method="post" >
{%else%}
<form action="/login/" method="post" >
{% endif %}
{% csrf_token %}
username:
<input type="text" name="username" value="{{ username }}" /><br />
password:
<input type="password" name="password" value="" /><br />
<input type="submit" value="Log In"/>
{% debug %}
</form>
5 ответов
ваш код в порядке, единственная проблема заключается в том, что в форме вы передаете next
атрибут как сообщение, потому что метод post
. В представлениях вы пытаетесь получить внутри get
словарь, который очевидно не существует.
вы должны объявить html-форму action
как это для того, чтобы ваш вид работы.
{% if next %}
<form action="/login/?next={{next}}" method="post" >
{%else%}
<form action="/login/" method="post" >
{% endif %}
{% csrf_token %}
username:
<input type="text" name="username" value="{{ username }}" /><br />
password:
<input type="password" name="password" value="" /><br />
<input type="submit" value="Log In"/>
{% debug %}
</form>
там, если есть next
переменная, то вы включаете в url
для получения его в качестве параметра get. Если нет, то форма не включает его.
это лучший подход, но вы также можете исправить это в своих представлениях, запросив next
С POST
словарь такой:
return HttpResponseRedirect(request.POST.get('next'))
обратите внимание, что это будет работать только если в шаблоне account_login
и переменная под названием next
. Вы должны создать его в представлениях и передать его шаблону при его визуализации.
обычно в шаблоне вы бы сделали что-то вроде это:
# this would be hardcoded
next = '/issueapp/1628/view/22'
# you may add some logic to generate it as you need.
и вы тут:
return render_to_response(
'account_login.html',
{
'state':state,
'username': username,
'next':next
},
context_instance=RequestContext(request)
)
надеюсь, что это помогает!
короче
Я бы определил в вашем представлении функцию next_page = request.GET['next']
и затем перенаправить на него return HttpResponseRedirect(next_page)
поэтому вам никогда не нужно менять шаблоны; просто установите @login_required
и ты в порядке.
например:
пользователь пытается открыть - пока не зашли в https://www.домен.tld / аккаунт/. Django перенаправляет его, потому что @login_required
имеет значение defined LOGIN_URL
в вашем settings.py - ... Метод UserLogin
теперь пытается GET
на next
параметр и перенаправляет на него, если пользователь входит в систему.
settings.py
LOGIN_URL = '/login/'
urls.py
url(r'^account/', account, name='account'),
url(r'^login/$', UserLogin, name='login'),
views.py
@login_required
def account(request):
return HttpResponseRedirect("https://www.domain.tld/example-redirect/")
def UserLogin(request):
next_page = request.GET['next']
if request.user.is_authenticated():
return HttpResponseRedirect(next_page)
else:
if request.method == 'POST':
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(email=username, password=password)
if user is not None and user.is_active:
login(request, user)
return HttpResponseRedirect(next_page)
else:
error_msg = 'There was an error!'
return render(request, "login", {'form': form, 'error_msg': error_msg})
else:
error_msg = "There was an error!"
return render(request, "login", {'form':form, 'error_msg':error_msg})
else:
form = UserLoginForm()
return render(request, "login", {'form': form})
Если вы хотите быть более общим, вы можете просто сделать что-то вроде этого, которое передает любой из параметров GET при публикации формы:
<form action="/path-to-whatever/{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" method="post">
вместо назначения next
в вашем представлении и передаче его в шаблон, не чище ли использовать ?next={{request.path}}
в шаблоне. (Не забудьте включить django.core.context_processors.request
на settings.py
, который обычно включен по умолчанию в django 1.6)
вот ссылка рассказывает о том же
https://docs.djangoproject.com/en/1.6/topics/auth/default/#the-raw-way
<form action="/login/?next={{request.path}}" method="post" >
требуется код.
Примечание:
вы можно получить текущий url с помощью request.path
С view
также.
спасибо буфер. Я просто скопировал и вставил ваш комментарий, попробовав его сам в своем собственном коде.
просто поставить
<form action="" method="post" >
пустое действие 'what ever current complete url is
'