pkout
pkout

Reputation: 6736

Hierarchical URLs in Django

Is there a way to implement hierarchical query pattern in Django? As far as I know, the framework only allows to route to views by parsing URLs of a specific format, like:

/customers/{order} -> customer.views.show_orders(order)

But what if I need something like this:

/book1/chapter1/section1/paragraph1/note5 -> notes.view.show(note_id)

where note_id is the id of the last part of the URL, but the URL could have different number of components:

/book1/chapter1
/book1/chapter1/section1
etc.

Each time, it would point to the relevant part of the book depth depending on the depth. Is this doable?

I know there is this: https://github.com/MrKesn/django-mptt-urls, but I am wondering if there is another solution. This isn't ideal for me.

Upvotes: 0

Views: 1233

Answers (3)

pkout
pkout

Reputation: 6736

For those who really need a variable-depth URL structure and need the URL to consist strictly of slugs, not IDs, knowing all the components of the URL is critical to retrieve the correct record from the database. Then, the only solution I can think of is using:

 url(r'^.*/$', notes.views.show, name='show')

and then parsing the content of the URL to get the individual components after retrieving the URL in the view using the request.path call. This doesn't sound ideal, but it is a way to accomplish it.

Upvotes: 0

davko
davko

Reputation: 459

Use named groups to accomplish this: https://docs.djangoproject.com/en/dev/topics/http/urls/#named-groups

url(r'^book(?P<book_id>\d+)/chapter(?P<chapter_id>\d+)/section(?P<section_id>\d+)/paragraph(?P<paragraph_id>\d+)/note(?P<note_id>\d+)$', notes.view.show(book_id, chapter_id, section_id, paragraph_id, note_id)

Upvotes: 0

user764357
user764357

Reputation:

Django URLs are just regular expressions, so the simplest way would be to just ignore everything prior to the "note" section of the URL. For example:

url(r'^.*/note(?P<note_id>[0-9]+)$', 'notes.view.show'),

However, this would ignore the book, chapter, paragraph components. Which would mean your notes would need unique ids across the system, not just within the book. If you needed to capture any number of the interim parts it would be more complicated.

I can't confirm this will work right now, but using non-capture groups in regular expressions, you should be able to capture an optional book and chapter like so:

url(r'^(?:book(?P<book_id>[0-9]+)/)?(?:chapter(?P<chapter_id>[0-9]+)/)?note(?P<note_id>[0-9]+)$', 'notes.view.show'),

Upvotes: 1

Related Questions