mirror of https://github.com/django/django.git
Merge branch 'url-tag-asvar'
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8716 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
2ca8cf3628
commit
c068bc184c
|
@ -351,22 +351,40 @@ class TemplateTagNode(Node):
|
||||||
return self.mapping.get(self.tagtype, '')
|
return self.mapping.get(self.tagtype, '')
|
||||||
|
|
||||||
class URLNode(Node):
|
class URLNode(Node):
|
||||||
def __init__(self, view_name, args, kwargs):
|
def __init__(self, view_name, args, kwargs, asvar):
|
||||||
self.view_name = view_name
|
self.view_name = view_name
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
self.asvar = asvar
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
from django.core.urlresolvers import reverse, NoReverseMatch
|
from django.core.urlresolvers import reverse, NoReverseMatch
|
||||||
args = [arg.resolve(context) for arg in self.args]
|
args = [arg.resolve(context) for arg in self.args]
|
||||||
kwargs = dict([(smart_str(k,'ascii'), v.resolve(context))
|
kwargs = dict([(smart_str(k,'ascii'), v.resolve(context))
|
||||||
for k, v in self.kwargs.items()])
|
for k, v in self.kwargs.items()])
|
||||||
|
|
||||||
|
|
||||||
|
# Try to look up the URL twice: once given the view name, and again
|
||||||
|
# relative to what we guess is the "main" app. If they both fail,
|
||||||
|
# re-raise the NoReverseMatch unless we're using the
|
||||||
|
# {% url ... as var %} construct in which cause return nothing.
|
||||||
|
url = ''
|
||||||
try:
|
try:
|
||||||
return reverse(self.view_name, args=args, kwargs=kwargs)
|
url = reverse(self.view_name, args=args, kwargs=kwargs)
|
||||||
except NoReverseMatch:
|
except NoReverseMatch:
|
||||||
project_name = settings.SETTINGS_MODULE.split('.')[0]
|
project_name = settings.SETTINGS_MODULE.split('.')[0]
|
||||||
return reverse(project_name + '.' + self.view_name,
|
try:
|
||||||
args=args, kwargs=kwargs)
|
url = reverse(project_name + '.' + self.view_name,
|
||||||
|
args=args, kwargs=kwargs)
|
||||||
|
except NoReverseMatch:
|
||||||
|
if self.asvar is None:
|
||||||
|
raise
|
||||||
|
|
||||||
|
if self.asvar:
|
||||||
|
context[self.asvar] = url
|
||||||
|
return ''
|
||||||
|
else:
|
||||||
|
return url
|
||||||
|
|
||||||
class WidthRatioNode(Node):
|
class WidthRatioNode(Node):
|
||||||
def __init__(self, val_expr, max_expr, max_width):
|
def __init__(self, val_expr, max_expr, max_width):
|
||||||
|
@ -1041,21 +1059,30 @@ def url(parser, token):
|
||||||
|
|
||||||
The URL will look like ``/clients/client/123/``.
|
The URL will look like ``/clients/client/123/``.
|
||||||
"""
|
"""
|
||||||
bits = token.contents.split(' ', 2)
|
bits = token.contents.split(' ')
|
||||||
if len(bits) < 2:
|
if len(bits) < 2:
|
||||||
raise TemplateSyntaxError("'%s' takes at least one argument"
|
raise TemplateSyntaxError("'%s' takes at least one argument"
|
||||||
" (path to a view)" % bits[0])
|
" (path to a view)" % bits[0])
|
||||||
|
viewname = bits[1]
|
||||||
args = []
|
args = []
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
|
asvar = None
|
||||||
|
|
||||||
if len(bits) > 2:
|
if len(bits) > 2:
|
||||||
for arg in bits[2].split(','):
|
bits = iter(bits[2:])
|
||||||
if '=' in arg:
|
for bit in bits:
|
||||||
k, v = arg.split('=', 1)
|
if bit == 'as':
|
||||||
k = k.strip()
|
asvar = bits.next()
|
||||||
kwargs[k] = parser.compile_filter(v)
|
break
|
||||||
else:
|
else:
|
||||||
args.append(parser.compile_filter(arg))
|
for arg in bit.split(","):
|
||||||
return URLNode(bits[1], args, kwargs)
|
if '=' in arg:
|
||||||
|
k, v = arg.split('=', 1)
|
||||||
|
k = k.strip()
|
||||||
|
kwargs[k] = parser.compile_filter(v)
|
||||||
|
elif arg:
|
||||||
|
args.append(parser.compile_filter(arg))
|
||||||
|
return URLNode(viewname, args, kwargs, asvar)
|
||||||
url = register.tag(url)
|
url = register.tag(url)
|
||||||
|
|
||||||
#@register.tag
|
#@register.tag
|
||||||
|
|
|
@ -675,6 +675,29 @@ The template tag will output the string ``/clients/client/123/``.
|
||||||
<naming-url-patterns>`, you can refer to the name of the pattern in the ``url``
|
<naming-url-patterns>`, you can refer to the name of the pattern in the ``url``
|
||||||
tag instead of using the path to the view.
|
tag instead of using the path to the view.
|
||||||
|
|
||||||
|
Note that if the URL you're reversing doesn't exist, you'll get an
|
||||||
|
:exc:`NoReverseMatch` exception raised, which will cause your site to display an
|
||||||
|
error page.
|
||||||
|
|
||||||
|
**New in development verson:** If you'd like to retrieve a URL without displaying it,
|
||||||
|
you can use a slightly different call:
|
||||||
|
|
||||||
|
.. code-block:: html+django
|
||||||
|
|
||||||
|
{% url path.to.view arg, arg2 as the_url %}
|
||||||
|
|
||||||
|
<a href="{{ the_url }}">I'm linking to {{ the_url }}</a>
|
||||||
|
|
||||||
|
This ``{% url ... as var %}`` syntax will *not* cause an error if the view is
|
||||||
|
missing. In practice you'll use this to link to views that are optional:
|
||||||
|
|
||||||
|
.. code-block:: html+django
|
||||||
|
|
||||||
|
{% url path.to.view as the_url %}
|
||||||
|
{% if the_url %}
|
||||||
|
<a href="{{ the_url }}">Link to optional stuff</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
.. templatetag:: widthratio
|
.. templatetag:: widthratio
|
||||||
|
|
||||||
widthratio
|
widthratio
|
||||||
|
|
|
@ -896,6 +896,11 @@ class Templates(unittest.TestCase):
|
||||||
'url-fail02': ('{% url no_such_view %}', {}, urlresolvers.NoReverseMatch),
|
'url-fail02': ('{% url no_such_view %}', {}, urlresolvers.NoReverseMatch),
|
||||||
'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch),
|
'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch),
|
||||||
|
|
||||||
|
# {% url ... as var %}
|
||||||
|
'url-asvar01': ('{% url regressiontests.templates.views.index as url %}', {}, ''),
|
||||||
|
'url-asvar02': ('{% url regressiontests.templates.views.index as url %}{{ url }}', {}, '/url_tag/'),
|
||||||
|
'url-asvar03': ('{% url no_such_view as url %}{{ url }}', {}, ''),
|
||||||
|
|
||||||
### CACHE TAG ######################################################
|
### CACHE TAG ######################################################
|
||||||
'cache01': ('{% load cache %}{% cache -1 test %}cache01{% endcache %}', {}, 'cache01'),
|
'cache01': ('{% load cache %}{% cache -1 test %}cache01{% endcache %}', {}, 'cache01'),
|
||||||
'cache02': ('{% load cache %}{% cache -1 test %}cache02{% endcache %}', {}, 'cache02'),
|
'cache02': ('{% load cache %}{% cache -1 test %}cache02{% endcache %}', {}, 'cache02'),
|
||||||
|
|
Loading…
Reference in New Issue