Przekierowanie strony Python + Django

158

Jak wykonać proste przekierowanie (np. cflocationW ColdFusion lub header(location:http://)PHP) w Django?

Kyle Hayes
źródło

Odpowiedzi:

250

To proste:

from django.http import HttpResponseRedirect

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

Więcej informacji w oficjalnej dokumentacji Django

Aktualizacja: Django 1.0

Najwyraźniej istnieje lepszy sposób na zrobienie tego w Django teraz, używając generic views.

Przykład -

from django.views.generic.simple import redirect_to

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

    #etc...
)

Więcej informacji można znaleźć w dokumentacji widoków ogólnych . Kredyt - Carles Barrobés .

Aktualizacja # 2: Django 1.3+

W Django 1.5 redirect_to już nie istnieje i zostało zastąpione przez RedirectView . Kredyt dla Yonatan

from django.views.generic import RedirectView

urlpatterns = patterns('',
    (r'^one/$', RedirectView.as_view(url='/another/')),
)
Baishampayan Ghose
źródło
8
Nie jest to już najlepsza metoda od wersji Django 1.0. Zobacz tę odpowiedź: stackoverflow.com/questions/523356/python-django-page-redirect/…
Jake,
2
Dlaczego nie używać redirectfrom django.shortcuts?
Afshin Mehrabani
4
Używam('^pattern/$', lambda x: redirect('/redirect/url/'))
mrmagooey
5
Jest to już przestarzałe począwszy od Django 1.5. Zamiast tego użyj „RedirectView”: docs.djangoproject.com/en/1.5/ref/class-based-views/base/…
Yonatan
Właściwie to nie jest przestarzałe, co mówisz, jest przestarzałe? przekierować? Korzystając z tej metody nie wiem, jak przekazać wartość parametrów do lambda, tj. Url (r '^ (? P <location_id> \ d +) / $', lambda x: HttpResponseRedirect (reverse ('dailyreport_location', args = ['% (location_id)',]))) nie działa
radtek
113

W zależności od tego, czego chcesz (tj. Jeśli nie chcesz wykonywać żadnego dodatkowego przetwarzania wstępnego), łatwiej jest po prostu użyć redirect_toogólnego widoku Django :

from django.views.generic.simple import redirect_to

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

    #etc...
)

Zobacz dokumentację, aby uzyskać bardziej zaawansowane przykłady.


Do użycia Django 1.3+:

from django.views.generic import RedirectView

urlpatterns = patterns('',
    (r'^one/$', RedirectView.as_view(url='/another/')),
)
Carles Barrobés
źródło
+1 za używanie widoku ogólnego zamiast zaimplementowania własnego (nieważne jak proste), jak w (bieżącej) najczęściej głosowanej odpowiedzi.
Dzień
Czy ktoś ma jakieś przykłady, jeśli nie chcesz zrobić dodatkową wstępną obróbkę?
analityk chętny
1
Następnie sugerowałbym albo napisać niestandardowy widok, który przetwarza, a następnie wywołuje widok ogólny, lub napisać dekorator, np. Pre_process i ozdobić widok ogólny: (r '^ one / $', pre_process (redirect_to), {'url ':' / another / '})
Carles Barrobés
1
@niallsco: jeśli chcesz wykonać dodatkowe przetwarzanie, najlepiej użyć skrótu do przekierowania, jak opisał Kennu tutaj
Lie Ryan.
1
W django 1.4, importowanie redirect_to daje ostrzeżenie o depracacji.
joctee
38

W rzeczywistości istnieje prostszy sposób niż posiadanie widoku dla każdego przekierowania - możesz to zrobić bezpośrednio w urls.py:

from django.http import HttpResponsePermanentRedirect

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

Cel może być wywoływalny, jak również ciąg , którego tutaj używam.

Miś
źródło
2
To prawda, ale używanie redirect_toogólnego widoku dołączonego do django jest jeszcze prostsze i bardziej czytelne. Zobacz odpowiedź Carles stackoverflow.com/questions/523356/python-django-page-redirect/…
Dzień
28

Od wersji Django 1.1 możesz także użyć prostszego skrótu do przekierowań :

from django.shortcuts import redirect

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

Pobiera również opcjonalny stały argument słowa kluczowego = True.

Kennu
źródło
14

Jeśli chcesz przekierować cały podfolder, urlargument w RedirectView jest w rzeczywistości interpolowany , więc możesz zrobić coś takiego w 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')),
]

?P<path>Przechwytywania ty zostaną uwzględnione RedirectView. Ta przechwycona zmienna zostanie następnie zastąpiona w urlargumencie, który podałeś, podając nam, /new_path/yay/mypathczy oryginalna ścieżka była /old/yay/mypath.

Możesz również zrobić, ….as_view(url='…', query_string=True)jeśli chcesz również skopiować ciąg zapytania.

odinho - Velmont
źródło
10

W przypadku Django w wersji 1.3 podejście oparte na klasach jest następujące:

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

Ten przykład znajduje się w urls.py

Zlatko
źródło
6

Strzec się. Zrobiłem to na serwerze deweloperskim i chciałem to później zmienić.

Musiałem wyczyścić moje pamięci podręczne, aby to zmienić. Aby uniknąć tego drapania głowy w przyszłości, udało mi się zrobić to tymczasowo w następujący sposób:

from django.views.generic import RedirectView

url(r'^source$', RedirectView.as_view(permanent=False, 
                                      url='/dest/')),
Gringo Suave
źródło
1

page_path = zdefiniuj w urls.py

def deletePolls(request):
    pollId = deletePool(request.GET['id'])
    return HttpResponseRedirect("/page_path/")
Moddasir
źródło
0

To powinno działać w większości wersji django, używam go w 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'),
    ....
)

W tym rozwiązaniu nadal możesz używać nazwy wzorca adresu URL zamiast adresu URL zakodowanego na stałe. Parametr location_id z adresu URL jest przekazywany do funkcji lambda.

radtek
źródło