Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redirect url pattern with variables from urls.py in Django?

I'd like to redirect url pattern with variables from urls.py.

I refer other stackoverflow solution, but I don't know when url having a variable like following code.

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

With this code, django will redirect /permalink/1/foo/ to /permalink/(?P<id>\d+)/, not the /permalink/1/.

Is there any solution without using views.py?

Of course I know solution using controller, but I wonder is there any simpler solution with using url pattern.

like image 856
Chemical Programmer Avatar asked Jul 27 '15 18:07

Chemical Programmer


People also ask

How do I redirect in urls py Django?

Django Redirects: A Super Simple Example Just call redirect() with a URL in your view. It will return a HttpResponseRedirect class, which you then return from your view. Assuming this is the main urls.py of your Django project, the URL /redirect/ now redirects to /redirect-success/ .

How do I create URL patterns in Django?

Here's an example URLconf and view: # URLconf from django.urls import path from . import views urlpatterns = [ path('blog/', views.page), path('blog/page<int:num>/', views.page), ] # View (in blog/views.py) def page(request, num=1): # Output the appropriate page of blog entries, according to num. ...

What is dynamic URL routing in Django?

Being able to capture one or more values from a given URL during an HTTP request is an important feature Django offers developers. We already saw a little bit about how Django routing works, but those examples used hard-coded URL patterns. While this does work, it does not scale.


1 Answers

Passing url='/permalink/(?P<id>\d+)/' to RedirectView will not work, because the view does not substitute the named arguments in the url.

However, RedirectView lets you provide the pattern_name instead of the url to redirect to. The url is reversed using the same args and kwargs that were passed for the original view.

This will work in your case, because both url patterns have one named 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"),
]

If the target url pattern uses other arguments, then you can't use url or pattern_name. Instead, you can subclass RedirectView and override 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()

It would be good practice to put QuerystringRedirect in your views module. You would then add the view to your url patterns with something like:

urlpatterns = [
    url(r'^permalink/$', views.QuerystringRedirect.as_view(), name="original_view"),
    url(r'^permalink/(?P<id>\d+)/$', views.permalink, name="target_view"),
]
like image 197
Alasdair Avatar answered Sep 18 '22 10:09

Alasdair