Micah
Micah

Reputation: 116050

Django routing issue

I have this route:

url(r'^profile/(?P<user_id>\d+)/?(.+)$', Profile.as_view())

The problem is that when I go to /profile/12345 the last digit gets cut off when being passed in to the handler. So I get user_id=1234. However if I go to /profile/12345/ or /profile/12345/user_namethenuser_id=12345` like I expect it. Does anyone have any idea why my last digit is getting cut off?

Upvotes: 1

Views: 145

Answers (2)

Paulo Almeida
Paulo Almeida

Reputation: 8061

The last digit is getting captured by the .+ pattern. It works if you switch to .*:

>>> a = re.compile('profile/(?P<user_id>\d+)/?(.+)')
>>> s = a.search("/profile/1234")
>>> s.groups()
('123', '4')

>>> a = re.compile('profile/(?P<user_id>\d+)/?(.*)')
>>> s = a.search("/profile/1234")
>>> s.groups()
('1234', '')
>>> s.groupdict()
{'user_id': '1234'}

See alecxe's answer too. I don't know if what you are doing is a good practice. I'd probably split that into two different patterns pointing to the same view.

Upvotes: 1

alecxe
alecxe

Reputation: 473763

Your regex is actually capturing the last char of the url:

>>> import re
>>> re.search("(?P<user_id>\d+)/?(.+)", "/profile/12345").groups()
('1234', '5')
>>> re.search("(?P<user_id>\d+)/?(.+)", "/profile/12345/").groups()
('12345', '/')

Try the simpler one instead:

url(r'^profile/(?P<user_id>\d+)$', Profile.as_view())

Note that you don't actually need to take care of / at the end (quote from this answer):

In Django URLs without forward slashes automatically have a forward slash appended to them. This is a preference of the Django developers and not a hard-coded rule of the web (I think it's actually a setting in Django).

Also see:

Hope that helps.

Upvotes: 2

Related Questions