regexdjangourl-patternurlconf

Django urlpatterns frustrating problem with trailing slashes


All of the examples I can find of urlpatterns for django sites have a separate entry for incoming urls that have no leading slash, or the root folder. Then they handle subfolders on each individual line. I don't understand why a simple

/?

regular expression doesn't permit these to be on one simple line.

Consider the following, let's call the Django project Baloney and the App name is Cheese. So in the project urls.py we have something like this to allow the apps urls.py to handle it's requests...

urlpatterns = patterns('',
    (r'^cheese/', include('Baloney.Cheese.urls')),
)

then inside of the Cheese apps urls.py, I don't understand why this one simple line would not trigger as true for all incoming url subpaths, including a blank value...

urlpatterns = patterns('',
    (r'^(?P<reqPath>.*)/?$', views.cheeseapp_views),
)

Instead, it matches the blank case, but not the case of a value present. So...

http://baloneysite.com/cheese/        -->   MATCHES THE PATTERN
http://baloneysite.com/cheese/swiss   -->   DOES NOT MATCH

Basically I want to capture the reqPath variable to include whatever is there (even blank or '') but not including any trailing slash if there is one.

The urls are dynamic slugs pulled from the DB so I do all the matching up to content in my views and just need the url patterns to forward the values along. I know that the following works, but don't understand why this can't all be placed on one line with the /? regular expression before the ending $ sign.

(r'^$', views.cheeseapp_views, {'reqPath':''}),
(r'^(?P<reqPath>.*)/$', views.cheeseapp_views),

Appreciate any insights.


Solution

  • I just tried a similar sample and it worked as you wrote it. No need for /?, .* would match that anyway. What is the exact error you are getting? Maybe you have your view without the request parameter? I.e. views.cheeseapp_views should be something like:

    def cheeseapp_views(request, reqPath):
        ...
    

    Edit:

    The pattern that you suggested catches the trailing slash into reqPath because * operator is greedy (take a look at docs.python.org/library/re.html). Try this instead:

    (r'^(?P<reqPath>.*?)/?$', views.cheeseapp_views) 
    

    note it's .*? instead of .* to make it non-greedy.