Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django dynamic urls

I am developing a website using Django as the backend, and I want to allow the customer to add new pages using the admin interface - so he enters a page title, an page alias that is used for nicer urls, and chooses whether he wants static content or an article based structure.

My approach is the following: I have created an app called sitemanager that consists of the page model described above, and a context processor that adds the pages to the context of my templates (for menus, etc.) and this works fine.

Of course, I also need to hook it into my url-file, but here is where the trouble begins: I can, thanks to the pythonic structure of Django, retrieve the Page model within urls.py, and generate my url pattern accordingly, and it does show, but Django seems to cache that file (which makes sense usually), so changes will take place only after a server restart. This obviously is not acceptable.

My first idea would be somehow bringing the admin application to resetting the url cache if new pages are added, or deleted, or aliases are modified (and only then, because caching generally is a good thing), but I have no idea how to start there.

Or maybe there is also a simpler solution that I am not seeing at the moment?

The relevant part of my urls.py looks basically like this:

from sitemanager.models import Page
static_pages = Page.objects.filter(static=True)
article_pages = Page.objects.filter(static=False)
for page in static_pages:
    pattern = r'^/'+page.alias+'/$'
    urlpatterns += patterns('',
        url(pattern, 'views.static_page',
            { 'active': page }
        )
    )
# Pretty much the same for the article pages,
# but with includes of another app

I hope I didn't make too many mistakes while stripping that code in my head!

like image 565
nijansen Avatar asked Feb 25 '12 00:02

nijansen


2 Answers

You can use named groups in the urls to pass data to views and it won't require any dynamic updating in the urls. The named part containing page.alias will be simply passed as a keyword argument to your view function. You can use it to get the actual Page object.

# urls.py
urlpatterns += patterns('',
   (r'^(?P<page_alias>.+?)/$', 'views.static_page'),
)

# views.py
def static_page(request, page_alias):    # page_alias holds the part of the url
    try:
        active = Page.objects.get(page_alias=page_alias)
    except Page.DoesNotExist:
        raise Http404("Page does not exist")
like image 172
Mariusz Jamro Avatar answered Oct 02 '22 01:10

Mariusz Jamro


You don't need a specific URL for each item in your entire database.

Without seeing your view, I would guess you can get away with one URL, or maybe a few url's.

As an example:

#urls.py
urlpatterns = patterns('yourapp.views',
url(r'^static_pages/(?P<static_pages_id>\d+)/(?P<True_or_False>\D+)$', your_view_here, name='your_name_here'),
)

#views.py
def your_view_here(request, static_pages_id, True_or_False):
    obj = get_object_or_404(Page, pk=static_pages_id)
    if True_or_False:
        #do something when True
like image 22
James R Avatar answered Oct 02 '22 00:10

James R