Redirection de page Python + Django

158

Comment effectuer une simple redirection (par exemple cflocationdans ColdFusion ou header(location:http://)pour PHP) dans Django?

Kyle Hayes
la source

Réponses:

250

C'est simple:

from django.http import HttpResponseRedirect

def myview(request):
    ...
    return HttpResponseRedirect("/path/")

Plus d'informations dans la documentation officielle de Django

Mise à jour: Django 1.0

Il existe apparemment une meilleure façon de faire cela dans Django en utilisant maintenant generic views.

Exemple -

from django.views.generic.simple import redirect_to

urlpatterns = patterns('',   
    (r'^one/$', redirect_to, {'url': '/another/'}),

    #etc...
)

Il y a plus dans la documentation des vues génériques . Crédit - Carles Barrobés .

Mise à jour n ° 2: Django 1.3+

Dans Django 1.5, redirect_to n'existe plus et a été remplacé par RedirectView . Crédit à Yonatan

from django.views.generic import RedirectView

urlpatterns = patterns('',
    (r'^one/$', RedirectView.as_view(url='/another/')),
)
Baishampayan Ghose
la source
8
Ce n'est plus la meilleure méthode depuis Django 1.0. Voir cette réponse: stackoverflow.com/questions/523356/python-django-page-redirect/...
Jake
2
Pourquoi ne pas utiliser redirectde django.shortcuts?
Afshin Mehrabani
4
J'utilise('^pattern/$', lambda x: redirect('/redirect/url/'))
mrmagooey
5
Ceci est déjà obsolète à partir de Django 1.5. Utilisez plutôt 'RedirectView': docs.djangoproject.com/en/1.5/ref/class-based-views/base/…
Yonatan
Ce n'est en fait pas obsolète, que dites-vous est obsolète? rediriger? En utilisant cette méthode, je ne sais pas comment passer la valeur des paramètres à lambda, c'est-à-dire url (r '^ (? P <location_id> \ d +) / $', lambda x: HttpResponseRedirect (reverse ('dailyreport_location', args = ['% (location_id)',]))) ne fonctionne pas
radtek
113

En fonction de ce que vous voulez (c'est-à-dire si vous ne souhaitez pas faire de prétraitement supplémentaire), il est plus simple d'utiliser simplement la redirect_tovue générique de Django :

from django.views.generic.simple import redirect_to

urlpatterns = patterns('',
    (r'^one/$', redirect_to, {'url': '/another/'}),

    #etc...
)

Consultez la documentation pour des exemples plus avancés.


Pour Django 1.3+, utilisez:

from django.views.generic import RedirectView

urlpatterns = patterns('',
    (r'^one/$', RedirectView.as_view(url='/another/')),
)
Carles Barrobés
la source
+1 pour utiliser une vue générique plutôt que d'implémenter la vôtre (aussi simple soit-elle) comme dans la réponse (actuelle) la plus votée.
Jour
Quelqu'un at - il des exemples pour si vous ne voulez faire avant un traitement supplémentaire?
eageranalyst
1
Ensuite, je suggérerais soit d'écrire une vue personnalisée qui effectue le traitement puis d'appeler la vue générique, soit d'écrire un décorateur, par exemple, pre_process et décorer la vue générique: (r '^ one / $', pre_process (redirect_to), {'url ':' / another / '})
Carles Barrobés
1
@niallsco: si vous souhaitez effectuer un traitement supplémentaire, il est préférable d'utiliser le raccourci de redirection comme décrit par Kennu ici
Lie Ryan
1
Dans django 1.4, l'importation de redirect_to donne un avertissement de dépréciation.
joctee
38

Il existe en fait un moyen plus simple que d'avoir une vue pour chaque redirection - vous pouvez le faire directement dans urls.py:

from django.http import HttpResponsePermanentRedirect

urlpatterns = patterns(
    '',
    # ...normal patterns here...
    (r'^bad-old-link\.php',
     lambda request: HttpResponsePermanentRedirect('/nice-link')),
)

Une cible peut être un appelable aussi bien qu'une chaîne , ce que j'utilise ici.

Teddy
la source
2
C'est vrai, mais l'utilisation de la redirect_tovue générique fournie avec django est encore plus simple et plus lisible. Voir la réponse de Carles stackoverflow.com/questions/523356/python-django-page-redirect/...
Jour
28

Depuis Django 1.1, vous pouvez également utiliser le raccourci de redirection plus simple :

from django.shortcuts import redirect

def myview(request):
    return redirect('/path')

Il prend également un argument de mot clé permanent = True facultatif.

Kennu
la source
14

Si vous souhaitez rediriger un sous-dossier entier, l' urlargument de RedirectView est en fait interpolé , vous pouvez donc faire quelque chose comme ça dans urls.py:

from django.conf.urls.defaults import url
from django.views.generic import RedirectView

urlpatterns = [
    url(r'^old/(?P<path>.*)$', RedirectView.as_view(url='/new_path/%(path)s')),
]

Le que ?P<path>vous capturez sera alimenté RedirectView. Cette variable capturée sera ensuite remplacée dans l' urlargument que vous avez donné, nous indiquant /new_path/yay/mypathsi votre chemin d'origine l'était /old/yay/mypath.

Vous pouvez également le faire ….as_view(url='…', query_string=True)si vous souhaitez également copier la chaîne de requête.

odinho - Velmont
la source
10

Avec Django version 1.3, l'approche basée sur les classes est:

from django.conf.urls.defaults import patterns, url
from django.views.generic import RedirectView

urlpatterns = patterns('',
    url(r'^some-url/$', RedirectView.as_view(url='/redirect-url/'), name='some_redirect'),
)

Cet exemple se trouve dans urls.py

Zlatko
la source
6

Il faut se méfier. J'ai fait cela sur un serveur de développement et je voulais le changer plus tard.

J'ai dû vider mes caches pour le changer. Afin d'éviter ce grattage à la tête à l'avenir, j'ai pu le rendre temporaire comme ceci:

from django.views.generic import RedirectView

url(r'^source$', RedirectView.as_view(permanent=False, 
                                      url='/dest/')),
Gringo Suave
la source
1

Vous pouvez le faire dans la section Admin. C'est expliqué dans la documentation.

https://docs.djangoproject.com/en/dev/ref/contrib/redirects/

Mcneo
la source
Bien que cela ne soit pas tout à fait pertinent pour ma question, il s'agit toujours d'un élément d'information intéressant.
Kyle Hayes
1

page_path = définir dans urls.py

def deletePolls(request):
    pollId = deletePool(request.GET['id'])
    return HttpResponseRedirect("/page_path/")
Moddasir
la source
0

Cela devrait fonctionner dans la plupart des versions de django, je l'utilise dans la version 1.6.5:

from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
urlpatterns = patterns('',
    ....
    url(r'^(?P<location_id>\d+)/$', lambda x, location_id: HttpResponseRedirect(reverse('dailyreport_location', args=[location_id])), name='location_stats_redirect'),
    ....
)

Vous pouvez toujours utiliser le nom du modèle d'URL au lieu d'une URL codée en dur avec cette solution. Le paramètre location_id de l'url est transmis à la fonction lambda.

Radtek
la source