Joe
Joe

Reputation: 33

URL routing in the Django framework

So I'm building a fairly simple website that allows users to create and edit profiles. I'm in the process of creating the URLs for the site, which follow the following "rules":

My code so far is as follows.

# my_site/urls.py

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^$', include('my_app.urls')),
    url(r'^profile/', include('my_app.urls')),
    url(r'^admin/', include(admin.site.urls)),
]

Part 2:

# my_app/urls.py

from django.conf.urls import url
from django.http import HttpResponse

from . import views

urlpatterns = [
   url(r'^(?P<username>[\w-]*)/$', views.profile, name='profile'),
   url(r'^(?P<username>[^\w-])/$', views.profile, name='profile'), # still link to the profile
   url(r'^$', views.home, name="home"),
]

With this code, when the user enters www.mysite.com/profile, the user is redirected to the home page, but the address bar still reads www.mysite.com/profile, which I do not want. I want it to read www.mysite.com. Also, the 3rd rule in the rule list I gave above is not obeyed. I was thinking of having a URL "cleaning" function, which trims unwanted parts of the URL, but I have no idea how to do this. Any help would be greatly appreciated.

Thank you very much.

Upvotes: 0

Views: 4551

Answers (1)

Anentropic
Anentropic

Reputation: 33903

To get the path in the browser to change you need to use an actual http redirect, not just a fallback in Django url matching.

# my_site/urls.py

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^$', include('my_app.urls')),
    url(r'^admin/', include(admin.site.urls)),
]


# my_app/urls.py

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

from . import views

urlpatterns = [
   url(r'^profile/(?P<username>[^/]+)/$', views.profile, name='profile'),
   url(r'^profile/(?P<username>[^/]+)/(.*)?', RedirectView.as_view(pattern_name='profile')),
   url(r'^profile/$', RedirectView.as_view(pattern_name='home')),
   url(r'^$', views.profile, name="home"),
]

to explain:

  • ^profile/(?P<username>[^/]+)/$ matches mysite.com/profile/my-user-name/ with no junk at the end
  • '^profile/(?P<username>[^/]+)/(.*)?' matches the case with junk at the end (after a valid username and /) ...you want to require the slash before looking for junk portion otherwise if you have two users john and johnsmith you would always match johnsmith in url as the john user (treating the smith as extra junk). We then do a real http redirect to the canonical profile url
  • '^profile/$' matches just mysite.com/profile/ and does a real http redirect to home page

for more about redirecting see: https://stackoverflow.com/a/15706497/202168

also of course the docs:
https://docs.djangoproject.com/en/1.8/ref/class-based-views/base/#redirectview
https://docs.djangoproject.com/en/1.8/topics/http/shortcuts/#redirect

Upvotes: 1

Related Questions