2015-07-27 38 views
8

Chciałbym przekierować wzorzec adresu URL ze zmiennymi z urls.py.Jak przekierować wzorzec adresu URL za pomocą zmiennych z urls.py w Django?

Mam na myśli other stackoverflow solution, ale nie wiem, kiedy adres URL ma zmienną podobną do poniższego kodu.

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


urlpatterns = patterns(
    url(
     r'^permalink/(?P<id>\d+)/foo/$', 
     RedirectView.as_view(url='/permalink/(?P<id>\d+)/') 
    ), 
) 

Z tym kodem, Django przekieruje /permalink/1/foo/ do /permalink/(?P<id>\d+)/, a nie /permalink/1/.

Czy istnieje rozwiązanie bez użycia views.py?

Oczywiście znam rozwiązanie za pomocą kontrolera, ale zastanawiam się, czy istnieje jakieś prostsze rozwiązanie z wykorzystaniem wzorca URL.

Odpowiedz

10

Przejście od url='/permalink/(?P<id>\d+)/' do RedirectView nie będzie działać, ponieważ widok nie zastępuje nazwanych argumentów w adresie URL.

Jednak RedirectView pozwala podać pattern_name zamiast url do przekierowania. Adres URL jest odwrócony, używając tych samych argumentów i kwargów, które zostały przekazane dla oryginalnego widoku.

To zadziała w twoim przypadku, ponieważ oba wzorce adresów URL mają jeden nazwany argument: id.

urlpatterns = [ 
    url(r'^permalink/(?P<id>\d+)/foo/$', 
     RedirectView.as_view(pattern_name="target_view"), 
     name="original_view"), 
    url(r'^permalink/(?P<id>\d+)/$', views.permalink, name="target_view"), 
] 

Jeżeli wzorzec docelowy URL wykorzystuje inne argumenty, to nie można używać url lub pattern_name. Zamiast tego można podklasę RedirectView zastąpić get_redirect_url.

from django.core.urlresolvers import reverse 
from django.views.generic import RedirectView 

class QuerystringRedirect(RedirectView): 
    """ 
    Used to redirect to remove GET parameters from url 

    e.g. /permalink/?id=10 to /permalink/10/ 
    """ 

    def get_redirect_url(self): 
     if 'id' in self.request.GET: 
      return reverse('target_view', args=(self.request.GET['id'],)) 
     else: 
      raise Http404() 

To byłaby dobra praktyka, aby umieścić QuerystringRedirect w module widoki. Następnie dodaj widok do wzorców adresów URL z czymś podobnym:

urlpatterns = [ 
    url(r'^permalink/$', views.QuerystringRedirect.as_view(), name="original_view"), 
    url(r'^permalink/(?P<id>\d+)/$', views.permalink, name="target_view"), 
]