Question

I'm looking for an easy way to compose URLs in the frontend with JavaScript. Let's take the URL patterns from the Django tutorial as an example:

urlpatterns = [
    # ex: /polls/
    url(r'^$', views.index, name='index'),
    # ex: /polls/5/
    url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
    # ex: /polls/5/results/
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
    # ex: /polls/5/vote/
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

I'd like to create a template from an URL name reference (I'm using MustacheJS in the example, but I'm not fixed on any particular syntax):

assert get_url_template('detail') == "/polls/{{ question_id }}/"
assert get_url_template('results') == "/polls/{{ question_id }}/results/"

In the frontend, I would simple supply question_id and get a complete URL. Of course, this has to work for most if not all URL patterns.

Is there any easy way to do this or do I have to hack something together based on Django's urlresolver?

Was it helpful?

Solution 2

I've managed to hack something simple which does what I wanted, maybe it'll be useful for someone. It's a template tag which replaces named groups with {{ name }} sequences and takes the URL name as a single parameter.

import re

from django import template
from django.core.urlresolvers import get_resolver, get_urlconf   

register = template.Library()

@register.simple_tag
def data_url(urlname):

    urlconf = get_urlconf()
    resolver = get_resolver(urlconf)

    if urlname not in resolver.reverse_dict:
        return ""

    url = resolver.reverse_dict[urlname][0][-1][0]
    url = re.sub(r'%\((.*?)\)s', '{{ \g<1> }}', url)

    return "/%s" % url

OTHER TIPS

There are a bunch of JS libraries which will do this. A quick google showed up django-js-reverse which looks quite nice, but has some open issues which are worth a look. You could always fork and fix, or at the least see how they do it.

[EDIT] Alternatively, if you want to avoid the ajax route, you could write a Django inclusion tag which (somehow - TBC) imports the urlconf and renders a template which lays out the url syntax for each in a JS data structure, wrapped in a block, so that they're all loaded into the template and available. It's not a particularly pretty solution, though...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top