Django

Code

Changeset 4494

Show
Ignore:
Timestamp:
02/12/07 22:24:58 (2 years ago)
Author:
mtredinnick
Message:

Fixed #2606 -- Added tag for working out the URL of a particular view function.
All work done by Ivan Sagalaev.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/template/defaulttags.py

    r4052 r4494  
    316316        return self.mapping.get(self.tagtype, '') 
    317317 
     318class URLNode(Node): 
     319    def __init__(self, view_name, args, kwargs): 
     320        self.view_name = view_name 
     321        self.args = args 
     322        self.kwargs = kwargs 
     323       
     324    def render(self, context): 
     325        from django.core.urlresolvers import reverse, NoReverseMatch 
     326        args = [arg.resolve(context) for arg in self.args] 
     327        kwargs = dict([(k, v.resolve(context)) for k, v in self.kwargs.items()]) 
     328        try: 
     329            return reverse(self.view_name, args=args, kwargs=kwargs) 
     330        except NoReverseMatch: 
     331            try: 
     332                project_name = settings.SETTINGS_MODULE.split('.')[0] 
     333                return reverse(project_name + '.' + self.view_name, args=args, kwargs=kwargs) 
     334            except NoReverseMatch: 
     335                return '' 
     336 
    318337class WidthRatioNode(Node): 
    319338    def __init__(self, val_expr, max_expr, max_width): 
     
    869888templatetag = register.tag(templatetag) 
    870889 
     890def url(parser, token): 
     891    """ 
     892    Returns an absolute URL matching given view with its parameters. This is a 
     893    way to define links that aren't tied to a particular url configuration: 
     894     
     895        {% url path.to.some_view arg1,arg2,name1=value1 %} 
     896     
     897    The first argument is a path to a view. It can be an absolute python path 
     898    or just ``app_name.view_name`` without the project name if the view is 
     899    located inside the project.  Other arguments are comma-separated values 
     900    that will be filled in place of positional and keyword arguments in the 
     901    URL. All arguments for the URL should be present. 
     902 
     903    For example if you have a view ``app_name.client`` taking client's id and 
     904    the corresponding line in a urlconf looks like this: 
     905     
     906        ('^client/(\d+)/$', 'app_name.client') 
     907     
     908    and this app's urlconf is included into the project's urlconf under some 
     909    path: 
     910     
     911        ('^clients/', include('project_name.app_name.urls')) 
     912     
     913    then in a template you can create a link for a certain client like this: 
     914     
     915        {% url app_name.client client.id %} 
     916     
     917    The URL will look like ``/clients/client/123/``. 
     918    """ 
     919    bits = token.contents.split(' ', 2) 
     920    if len(bits) < 2: 
     921        raise TemplateSyntaxError, "'%s' takes at least one argument (path to a view)" % bits[0] 
     922    args = [] 
     923    kwargs = {} 
     924    if len(bits) > 2: 
     925        for arg in bits[2].split(','): 
     926            if '=' in arg: 
     927                k, v = arg.split('=', 1) 
     928                kwargs[k] = parser.compile_filter(v) 
     929            else: 
     930                args.append(parser.compile_filter(arg)) 
     931    return URLNode(bits[1], args, kwargs) 
     932url = register.tag(url) 
     933 
    871934#@register.tag 
    872935def widthratio(parser, token): 
  • django/trunk/docs/templates.txt

    r4492 r4494  
    830830Note: ``opencomment`` and ``closecomment`` are new in the Django development version. 
    831831 
     832url 
     833~~~ 
     834 
     835Returns an absolute URL matching a given view function. This is a way to 
     836define links that aren't tied to a particular url configuration. 
     837 
     838:: 
     839 
     840    {% url path.to.some_view arg1,arg2,name1=value1 %} 
     841 
     842The first argument is a path to a view function. It can be an absolute python 
     843path or just ``app_name.view_name`` without the project name if the view is 
     844located inside the project.  Other arguments are comma-separated values that 
     845will be use as positional and keyword arguments in the URL. All arguments 
     846needed by the URL resolver should be present. 
     847 
     848For example, suppose you have a view ``app_name.client`` taking client's id 
     849and the corresponding line in a urlconf looks like this:: 
     850 
     851    ('^client/(\d+)/$', 'app_name.client') 
     852 
     853If this app's urlconf is included into the project's urlconf under a path 
     854such as 
     855 
     856:: 
     857 
     858    ('^clients/', include('project_name.app_name.urls')) 
     859 
     860then, in a template, you can create a link to this view like this:: 
     861 
     862    {% url app_name.client client.id %} 
     863 
     864The URL rendered in the template will then look like ``/clients/client/123/``. 
     865 
    832866widthratio 
    833867~~~~~~~~~~ 
  • django/trunk/tests/regressiontests/templates/tests.py

    r4493 r4494  
    646646            'timeuntil04' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=1), 'b':NOW - timedelta(days=2)}, '1 day'), 
    647647            'timeuntil05' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=2), 'b':NOW - timedelta(days=2, minutes=1)}, '1 minute'), 
     648 
     649            ### URL TAG ######################################################## 
     650            # Successes 
     651            'url01' : ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'), 
     652            'url02' : ('{% url regressiontests.templates.views.client_action client.id,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), 
     653            'url03' : ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'), 
     654 
     655            # Failures 
     656            'url04' : ('{% url %}', {}, template.TemplateSyntaxError), 
     657            'url05' : ('{% url no_such_view %}', {}, ''), 
     658            'url06' : ('{% url regressiontests.templates.views.client no_such_param="value" %}', {}, ''), 
    648659        } 
    649660 
  • django/trunk/tests/urls.py

    r3708 r4494  
    88    (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}), 
    99    (r'^accounts/logout/$', 'django.contrib.auth.views.login'), 
     10 
     11    # test urlconf for {% url %} template tag 
     12    (r'^url_tag/', include('regressiontests.templates.urls')), 
    1013)