1

I want to catch from all urls like

example.com/<page_path> or example.com/<page_path>/

the <page_path> part. The variable could be empty (redirect to example.com/start) or a path to the desired page (most of the time a simple string, but can also have slashes in it)

This is my current urls.py which seems to work:

urlpatterns = [
    url(r'^/$', RedirectView.as_view(url="start"), name='index'),
    url(r'^$', RedirectView.as_view(url="start"), name='index'),
    url(r'^(?P<page>.+)/$', views.PageView.as_view(), name='page'),
    url(r'^(?P<page>.+)$', views.PageView.as_view(), name='page'),
]

But now I tried to simplify the expression and came up with this:

urlpatterns = [
    url(r'^/?$', RedirectView.as_view(url="start"), name='index'),
    url(r'^(?P<page>.+)/?$', views.PageView.as_view(), name='page'),
]

I want to capture everything except if there is a trailing slash.

Strange is, this works for

  • example.com
  • example.com/
  • example.com/start

but not for

  • example.com/start/

Can someone point my error out?

7
  • 1
    change your urls to : url(r'^(?P<page>[-\w]+)/?$', views.PageView.as_view(), name='page'), Commented Oct 22, 2015 at 11:42
  • 3
    i have only changed the regx. Instead of '.+' use '[-\w]+', this should work. Commented Oct 22, 2015 at 11:55
  • 2
    what @anush said, your current regex is too greedy and is grabbing the slash on the end too as part of page, so there is nothing left for the /? part to work on Commented Oct 22, 2015 at 12:42
  • 2
    You don't need r'^/?$, r'^$' will work fine whether you type example.com or example.com/. Commented Oct 22, 2015 at 13:23
  • 1
    If you look at the request for http://example.com and http://example.com/ in your logs, you'll see "GET / HTTP/1.1", whether or not you include the slash. Django strips the leading slash from the request before resolving the url. So if you have r'^/$', it will actually match //, which isn't what you want. You don't need a leading slash in r'^$' in the same way as you don't put a leading slash in r'^(?P<page>.+)'. Django 1.9 will check your url patterns for this mistake, and a couple of others. Commented Oct 22, 2015 at 13:54

2 Answers 2

3

There is a Django setting called APPEND_SLASH with default value True:

When set to True, if the request URL does not match any of the patterns in the URLconf and it doesn’t end in a slash, an HTTP redirect is issued to the same URL with a slash appended. Note that the redirect may cause any data submitted in a POST request to be lost.

The APPEND_SLASH setting is only used if CommonMiddleware is installed.

Source: Django documentation: Settings

Sign up to request clarification or add additional context in comments.

1 Comment

Interesting, but my problem is more the other way around. I want urls that end with a slash and don't match any pattern to be redirected to the same URL without the slash.
2

Thanks to your comments I could fix it with this:

urlpatterns = [
    url(r'^$', RedirectView.as_view(url="start"), name='index'),
    url(r'^(?P<page>.+?)/?$', views.PageView.as_view(), name='page'),
]

The + quantifier was too greedy, so I replaced it with the non-greedy version +?.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.