2009-04-30 30 views
148

Estoy tratando de crear un sitio web simple con una funcionalidad de inicio de sesión muy similar a la aquí en SO. El usuario debería poder navegar por el sitio como un usuario anónimo y habrá un enlace de inicio de sesión en cada página. Al hacer clic en el enlace de inicio de sesión, el usuario será llevado al formulario de inicio de sesión. Después de un inicio de sesión exitoso, el usuario debe regresar a la página desde donde hizo clic en el enlace de inicio de sesión. Supongo que tengo que pasar de alguna manera la url de la página actual a la vista que maneja el formulario de inicio de sesión, pero realmente no puedo hacer que funcione.Django: redirige a la página anterior después de iniciar sesión

EDIT: Me di cuenta. Me conecté al formulario de inicio de sesión al pasar la página actual como un parámetro GET y luego utilicé 'next' para redireccionar a esa página. ¡Gracias!

EDIT 2: Mi explicación no parece estar claro por lo que conforme a lo solicitado aquí está mi código: digamos que estamos en un foo.html página y que no se ha identificado Ahora nos gustaría tener un enlace. en foo.html que enlaza con login.html. Allí podemos iniciar sesión y luego ser redirigidos a foo.html. El enlace en foo.html se ve así:

 <a href='/login/?next={{ request.path }}'>Login</a> 

Ahora me escribió una vista de inicio de sesión personalizada que se ve algo como esto:

def login_view(request): 
    redirect_to = request.REQUEST.get('next', '') 
    if request.method=='POST': 
     #create login form... 
     if valid login credentials have been entered: 
     return HttpResponseRedirect(redirect_to) 
    #... 
    return render_to_response('login.html', locals()) 

Y la línea importante en login.html:

<form method="post" action="./?next={{ redirect_to }}"> 

Así que sí, eso es todo, espero que lo aclare.

+1

creo que el Las cosas de inicio de sesión de Django manejan eso para usted, ¿no le está funcionando? –

Respuesta

121

No es necesario hacer una vista extra para esto, la funcionalidad ya está integrado en

Primero, cada página con un enlace de inicio de sesión necesita conocer la ruta actual, y la forma más fácil es agregar el preprosessor de contexto de solicitud a settings.py (los 4 primeros son predeterminados), luego el objeto de solicitud estará disponible en cada solicitud :

settings.py:

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth", 
    "django.core.context_processors.debug", 
    "django.core.context_processors.i18n", 
    "django.core.context_processors.media", 
    "django.core.context_processors.request", 
) 

A continuación, agregue en la plantilla que desea el enlace de conexión:

base.html:

<a href="{% url django.contrib.auth.views.login %}?next={{request.path}}">Login</a> 

Esto añadirá un argumento GET a la página de inicio de sesión que apunta de nuevo a la página actual.

La plantilla de conectarse a continuación, puede ser tan simple como esto:

registro/login.html:

{% block content %} 
<form method="post" action=""> 
    {{form.as_p}} 
<input type="submit" value="Login"> 
</form> 
{% endblock %} 
+40

Yo personalmente uso esta solución, pero la única modificación que haría es que falla si 'request.path' es nulo, entonces lo hago' {% firstof request.path '/'%} ', de esa manera si la ruta de acceso de la solicitud no está disponible por algún motivo, el usuario es enviado a la página de inicio. – jorelli

+1

Estoy tratando de implementar su solución pero, cuando django.contrib.auth.views.login redirige (después de autenticar con éxito) la instancia del usuario no está en la solicitud, entonces user.is_authenticated() siempre devuelve False. ¿Alguna ayuda? – juankysmith

+3

Añadiendo en la parte superior de @jorelli, puede usar URL con nombre y hacer 'Login' en su lugar. – hobbes3

14

La autenticación integrada de Django funciona de la manera que desee.

Sus páginas de inicio de sesión incluyen una cadena de consulta next que es la página a la que volver después de iniciar sesión.

Mira http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required

+3

Bueno, el decorador de login_required funcionaría muy bien ya que establece 'next' a la página de la que procedo, pero cuando se utiliza el decorador, los usuarios anónimos no pueden ver el sitio porque se les redireccionará al formulario de inicio de sesión de inmediato. Creo que solo tengo que averiguar cómo establecer el valor de 'siguiente' a la url de la página de donde proviene el usuario. –

0

Ver documentos django para views.login(), proporciona un valor 'siguiente' (como un campo oculto) en el formulario de entrada a redireccionar después de una conexión exitosa.

+0

Sí, pero ¿cómo configuro 'siguiente' a la página de donde vengo? –

1

I vinculado al formulario de inicio de sesión al pasar la página actual como un parámetro GET y luego se utiliza 'siguiente' para redirigir a esa página. ¡Gracias!

24

esto puede no ser una "mejor práctica", pero he utilizado con éxito esto antes:.

return HttpResponseRedirect(request.META.get('HTTP_REFERER','/')) 
+8

Esto tiene un punto débil: algunos usuarios/navegadores tienen un referer pasajero apagado –

+4

También existe el problema en el caso en que un usuario llega a un formulario, rellena la información y luego la envía. El HTTP_REFERER es entonces la URL de la página del formulario, y no la URL de la página de donde vino el usuario en primer lugar. – LaundroMat

+1

Y si el primer envío involucró un error, el usuario corrige ... – Bryce

1

me encontré con el mismo problema. Esta solución permite que siga utilizando la vista de inicio de sesión genérica:

urlpatterns += patterns('django.views.generic.simple', 
    (r'^accounts/profile/$', 'redirect_to', {'url': 'generic_account_url'}), 
) 
1

En registration/login.html (anidado dentro templates carpeta) si se inserta la siguiente línea, la página hará que al igual que la página de administración de usuario originales de Django:

{% include "admin/login.html" %} 

Nota: El archivo solo debe contener las líneas anteriores.

19

admitiendo URL completas con param/valores que usted necesitaría:

?next={{ request.get_full_path|urlencode }} 

en lugar de simplemente:

?next={{ request.path }} 
+0

En realidad esta no es una buena idea, encontrará la cadena de consulta muy larga si tiene demasiados clics – dspjm

-2

También puede hacer esto

<input type="hidden" name="text" value="{% url 'dashboard' %}" /> 
+0

Respuesta incorrecta, pero el nombre = 'siguiente' parece factible, no probado. – WeizhongTu

Cuestiones relacionadas