Reputation: 395
I have a menu-content system in Django, where menu items are accessed by their keys and their contents through IDs. My URL mapping is:
url(r'^menu/(?P<item_key>[a-z/\-]*[a-z])/', views.menu, name='menu'),
url(r'^menu/(?P<item_key>[a-z/\-]*[a-z])/(?P<content_id>\d+)/', views.menu,\
name='menu_showById'),
The first one is the base view, where the user would land after clicking on an item through the navbar. The second one is for viewing a particular content in a menu item. views.menu
has an optional parameter called content_id with None
as default (in which case it views the newest content).
The navbar links work fine, pointing to the menu items as http://localhost:8000/menu/some-item/sub-item
. In this URL generated in the template using {% url 'data:menu' node.key %}
[1], /menu/
is the view and some-item/sub-item
is the item_key (example matches real use case; there are dashes and forward slashes in almost all of the item keys).
Through the base view, I click on a link generated with {% url 'data:menu_showById' menuItem.key cItem.id %}
as http://localhost:8000/menu/some-item/sub-item/2/
, to view the content with the ID 2. There's nothing wrong with the generated URLs, they look exactly as I want them to and the URL mapping regexes match them properly.
The problem is, while menu_showById
gets the item_key
parameter properly as some-item/sub-item
, the second parameter content_id
is never captured.
...Why?
^[1]: node
is a node in the django-mptt tree structure I use to keep my menu items.
Upvotes: 1
Views: 143
Reputation: 395
Lesson learned: Keep your URL regexes as strict as possible. The answer by scoopseven was the most obvious solution and an important rule in defining URLs, but using it to fix something like this kinda felt like a hack to me, and more importantly made the order of my URLs into one I didn't like. So I changed the base URL from
url(r'^menu/(?P<item_key>[a-z/\-]*[a-z])/', views.menu, name='menu')
to
url(r'^menu/(?P<item_key>[a-z/\-]*[a-z])/$', views.menu, name='menu')
and now it works like a charm.
Upvotes: 1
Reputation: 1777
The first regex is always matching, so content_id is never picked up. Try switching the order in urls.py.
Upvotes: 2