python - template - loginview django
¿Redirigir django después de iniciar sesión no funciona "siguiente" no publicar? (5)
En breve
next_page = request.GET[''next'']
en su función de vista next_page = request.GET[''next'']
y luego redirigir a ella return HttpResponseRedirect(next_page)
para que nunca tenga que cambiar las plantillas; simplemente configura @login_required
y estás bien.
Como ejemplo:
El usuario A intenta acceder, aunque no haya iniciado sesión, https://www.domain.tld/account/ . Django lo redirige porque @login_required
está establecido en el LOGIN_URL
definido en su settings.py. El método UserLogin
ahora intenta GET
el next
parámetro y redirige a él si el usuario A inicia sesión correctamente.
settings.py
LOGIN_URL = ''/login/''
urls.py
url(r''^account/'', account, name=''account''),
url(r''^login/$'', UserLogin, name=''login''),
vistas.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})
Esta pregunta ya tiene una respuesta aquí:
Tengo una página de inicio de sesión que funciona bien con la excepción de la redirección a la página de referencia. El usuario recibe un correo electrónico con un enlace directo dentro de la aplicación, ya que (en este ejemplo) no han iniciado sesión y se han redirigido a la página de inicio de sesión. Después de iniciar sesión correctamente, el usuario se redirige a una ruta codificada. Vea el ejemplo a continuación.
URL en el correo electrónico: http://localhost:8000/issueapp/1628/view/22
URL de la página de inicio de sesión: http://localhost:8000/login?next=/issueapp/1628/view/22
Vista de inicio de sesión (con redireccionamiento codificado):
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)
)
Vista de inicio de sesión (con "siguiente" redirección):
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)
)
La vista anterior da como resultado una excepción que "Key ''next'' not found in <QueryDict: {}>"
El formulario no parece estar publicando la variable "next", aunque esté en la url y en el formulario. He buscado y buscado por todas partes y no puedo entender por qué no está funcionando. ¿Algunas ideas?
Referencia adicional:
Plantilla de inicio de sesión:
{% 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 %}
EDITAR: ¡El siguiente código es el que ahora me funciona (gracias a la ayuda de Paulo Bu)! **
Vista de inicio de sesión:
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)
)
Plantilla de inicio de sesión:
{{ 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>
En lugar de asignar next
en tu vista y pasarlo a la plantilla, ¿no es más limpio usar ?next={{request.path}}
en tu plantilla. (Recuerde habilitar django.core.context_processors.request
en settings.py
, que por lo general se habilita de forma predeterminada en django 1.6)
Aquí está el enlace que dice sobre el mismo.
https://docs.djangoproject.com/en/1.6/topics/auth/default/#the-raw-way
<form action="/login/?next={{request.path}}" method="post" >
Es el código requerido.
Nota:
También puede obtener la url actual con request.path
desde la view
.
Gracias a buffer . Acabo de copiar y pegar tu comentario después de haberlo probado en mi propio código.
Sólo hay que poner
<form action="" method="post" >
Acción vacía '' what ever current complete url is
''
Si quieres ser más genérico, puedes hacer algo como esto, que pasa cualquiera de los parámetros GET cuando se publica el formulario:
<form action="/path-to-whatever/{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" method="post">
Su código está bien, el único problema es que en el formulario está pasando el next
atributo como una publicación porque el método es la post
. En las vistas, intenta obtener el next
parámetro dentro del diccionario de get
que es obvio que no está allí.
Debe declarar la action
formulario html de esta manera para que sus vistas funcionen.
{% 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>
Allí, si hay una next
variable, la incluirás en la url
para recuperarla como parámetro de obtención. Si no, el formulario no lo incluye.
Este es el mejor enfoque, pero también puede solucionarlo en sus vistas solicitando el next
al diccionario POST
esta manera:
return HttpResponseRedirect(request.POST.get(''next''))
Tenga en cuenta que esto solo funcionará si la plantilla account_login
tiene una variable llamada next
. Debe generarlo en las vistas y pasarlo a la plantilla cuando lo represente.
Normalmente, en la plantilla harías algo como esto:
# this would be hardcoded
next = ''/issueapp/1628/view/22''
# you may add some logic to generate it as you need.
y luego haces
return render_to_response(
''account_login.html'',
{
''state'':state,
''username'': username,
''next'':next
},
context_instance=RequestContext(request)
)
¡Espero que esto ayude!