web-dev-qa-db-fra.com

Django: redirection vers la page précédente après la connexion

J'essaie de construire un site Web simple avec une fonctionnalité de connexion très similaire à celle présentée ici sur SO. L'utilisateur doit pouvoir naviguer sur le site en tant qu'utilisateur anonyme et il y aura un lien de connexion sur chaque page. En cliquant sur le lien de connexion, l'utilisateur sera redirigé vers le formulaire de connexion. Après une connexion réussie, l'utilisateur doit être ramené à la page à partir de laquelle il a cliqué sur le lien de connexion en premier lieu. Je suppose que je dois en quelque sorte transmettre l'URL de la page en cours à la vue qui gère le formulaire de connexion, mais je ne parviens pas vraiment à le faire fonctionner.

EDIT: Je l'ai compris. Je me suis lié au formulaire de connexion en passant la page actuelle en tant que paramètre GET, puis utilisé "suivant" pour rediriger vers cette page. Merci!

EDIT 2: Mon explication n’a pas semblé être claire, c’est donc mon code qui a été demandé: nous sommes sur une page foo.html et nous ne sommes pas connectés. Nous aimerions maintenant avoir un lien sur foo.html à login.html. Là nous pouvons nous connecter et sont ensuite redirigés vers foo.html. Le lien sur foo.html ressemble à ceci:

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

Maintenant, j'ai écrit une vue de connexion personnalisée qui ressemble un peu à ceci:

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())

Et la ligne importante dans login.html:

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

Donc ouais c'est à peu près tout ça, j'espère que ça le rend clair.

166
jörg

Vous n'avez pas besoin de créer une vue supplémentaire pour cela, la fonctionnalité est déjà intégrée.

Tout d'abord, chaque page avec un lien de connexion doit connaître le chemin actuel. Le moyen le plus simple consiste à ajouter le préprocesseur du contexte de la requête à settings.py (les 4 premières sont la valeur par défaut), ensuite l'objet de la requête sera disponible dans chaque requête:

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",
)

Ensuite, ajoutez dans le modèle que vous voulez le lien de connexion:

base.html:

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

Cela ajoutera un argument GET à la page de connexion qui renvoie à la page en cours.

Le modèle de connexion peut alors être aussi simple que cela:

registration/login.html:

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

Ce n'est peut-être pas une "meilleure pratique", mais je l'ai déjà utilisé avec succès auparavant:

return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))
27
Grant

Pour prendre en charge les URL complètes avec param/values ​​dont vous avez besoin:

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

au lieu de juste:

?next={{ request.path }}
22
arntg

L'authentification intégrée de Django fonctionne comme vous le souhaitez.

Leurs pages de connexion incluent une chaîne de requête next qui est la page à laquelle revenir après la connexion.

Regardez http://docs.djangoproject.com/en/dev/topics/auth/#Django.contrib.auth.decorators.login_required

14
S.Lott

Dans registration/login.html (imbriqué dans le dossier templates) si vous insérez la ligne suivante, la page sera rendue comme la page de connexion d’administrateur d’origine de Django:

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

Remarque: le fichier doit contenir uniquement les lignes ci-dessus.

1
Harshith J.V.

J'ai rencontré le même problème. Cette solution me permet de continuer à utiliser la vue de connexion générique:

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

Je me suis lié au formulaire de connexion en passant la page actuelle en tant que paramètre GET, puis en utilisant "suivant" pour rediriger vers cette page. Merci!

1
jörg

Voir Django docs pour views.login () , vous fournissez une valeur 'next' (sous forme de champ masqué) sur le formulaire de saisie à rediriger après une connexion réussie. .

0
YHVH