1

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?

Micah
  • 111,873
  • 86
  • 233
  • 325

2 Answers2

2

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.

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
1

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.

Paulo Almeida
  • 7,803
  • 28
  • 36