Django urls having N number of optional parameters - django

I want to have same url pattern as khanacademy.org have in its videos. Suppose I opened a video having title "The Beauty of Algebra" its url will be http://www.khanacademy.org/math/algebra/introduction-to-algebra/v/the-beauty-of-algebra.
It shows three level of categories (math, algebra and introduction to algebra) in url. The same I want in django. Level of categories(no. of parameters) may increase up to N.
I didn't want to hard code the Urls like
url(r"^(?P<level_one>[a-zA-Z]+)/v/(?P<slug>[-\w]+)/$", "my_view", name="level_one"),
url(r"^(?P<level_one>[a-zA-Z]+)/(?P<level_two>[a-zA-Z]+)/v/(?P<slug>[-\w]+)/$", "my_view", name="level_two"),
url(r"^(?P<level_one>[a-zA-Z]+)/(?P<level_two>[a-zA-Z]+)/(?P<level_three>[a-zA-Z]+)/v/(?P<slug>[-\w]+)/$", "my_view", name="level_three"),
...
Thanks!

I don't believe it is possible to have a variable number of parameters in your urls.py. The best option may be to have a single generic catch-all url that points to a view where you write your own url dispatcher which is more complicated than what django's urls can provide.
You'd be able to parse the path and handle N number of levels within your view.

Related

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.
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'),
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)
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.

Django documentation, part3 understanding problems

I read the documentation of Django but now I am at a point where I need some explanation. It is on this site and I understand the views but I really don't get how the urls work. It looks pretty cryptic and confusing to me. Can anybody explain to me how the urls work and what their purpose is?
Your urls.py file is virtual. They do it this way so you don't need to worry about a static url to http://yoursite.com/polls/34. By using this number as a regular expression /(d+) you can keep it dynamic so one url with this regular expression can be millions of different polls.
when the url is requested that regular expression number (whether it's 1 or 13352) is sent to the view which then says, I need to query the database for a Poll that has a PrimaryKey (PK) of whatever this number is. If it's found the Poll object is sent to the template by the view. The template then displays all the data in the poll object.
The bottom line is using something like this you can have one line for a url which is essentially millions of different urls. I use this same format for a movies website I'm creating www.noobmovies.com. I follow the same structure for Stars, Movies and blogs. Essentially three lines of code has created urls for 10,000 pages or so.
There is a dedicated Django documentation page for that: https://docs.djangoproject.com/en/1.6/topics/http/urls/
Maybe it will help you?

cppcms url dispather with over 4 parameter

I started using cppcms to make a simple website + "service" that gets its input from the path like:
/maindb/2012/11/2/finalists/....
now i noticed that the nice url handling has only a regex dispatcher up to 4 parameters that will be given to the called function and a function without regex gets nothing at all not even the path.
Now what is the most feasible way to realize more than 4 parameters / subfolders.
Do I have to write my own url handling and if so where do i get the url from?
Is the url class public enough to iherit it and just extend it easiely for longer functions?
Or is there some other way how I am supposed to do it? (because 4 parameters seems kinda very less)
Two points:
If you have subfolders you are probably looking for organizing your URLs into hierarchy. See
http://cppcms.com/wikipp/en/page/cppcms_1x_tut_hierarchy
If you need more then 4 parameters you should:
Check if you really organize your application right (see above)
Combine several cases into single regex and split them afterwards in a parameters
For example (/\d\d\d\d/\d\d/\d\d)/(\w+) where the first would mach the data and not separatly year, month day.
P.S.: Url dispatcher is not designed to be derived from.

Django url pattern to retrieve query string parameters

I was about ready to start giving a jqgrid in a django app greater functionality (pagination, searching, etc). In order to do this it looks as though jqgrid sends its parameters in the GET to the server. I plan to write an urlpattern to pull out the necessary stuff (page number, records per page, search term, etc) so I can pass it along to my view to return the correct rows to the grid. Has anyone out there already created this urlpattern I am in search of?
Thanks much.
The answer to this was simpler than I realized. As stated in Chapter 7 of the djangobook in the section titled "Query string parameters" one can simply do something as follows, where "someParam" is the parameter in the query string you want to retrieve. However, Django is designed to be clean in that address bar at the top of the page so you should only use this option if you must.
The query string might look something like this.
http://somedomainname.com/?someString=1
The view might look like this.
def someView(request):
if 'someParam' in request.GET and request.GET['someParam']:
someParam = request.GET['someParam']
Hopefully this is of some help to someone else down the road.

Recursive URL Patterns CMS Style

Whenever I learn a new language/framework, I always make a content management system...
I'm learning Python & Django and I'm stuck with making a URL pattern that will pick the right page.
For example, for a single-level URL pattern, I have:
url(r'^(?P<segment>[-\w]+)/$', views.page_by_slug, name='pg_slug'),
Which works great for urls like:
http://localhost:8000/page/
Now, I'm not sure if I can get Django's URL system to bring back a list of slugs ala:
http://localhost:8000/parent/child/grandchild/
would return parent, child, grandchild.
So is this something that Django does already? Or do I modify my original URL pattern to allow slashes and extract the URL data there?
Thanks for the help in advance.
That's because your regular expression does not allow middle '/' characters. Recursive definition of url segments pattern may be possible, but anyway it would be passed as a chunk to your view function.
Try this
url(r'^(?P<segments>[-/\w]+)/$', views.page_by_slug, name='pg_slug'),
and split segments argument passed to page_by_slug() by '/', then you will get ['parent', 'child', 'grandchild']. I'm not sure how you've organized the page model, but if it is not much sophiscated, consider using or improving flatpages package that is already included in Django.
Note that if you have other kind of urls that does not indicate user-generated pages but system's own pages, you should put them before the pattern you listed because Django's url matching mechanism follows the given order.