参考:How do I construct a Django reverse/url using query args?
这是somepage.html
<a href={% query_urls from={{from}} to={{to}} %}> LOL LOSER</a>
首先转到somepage
次观看,然后点击任意按钮将重定向到move
次观看。
def move(request):
to = request.GET.get('to', 'None')
ffrom = request.GET.get('from', 'None')
#raise AssertionError(ffrom)
return render_to_response(request, "move.html", {'to': to, 'from': ffrom})
def somepage(request):
to = '../mydir'
ffrom = './heere.py'
return render_to_response(request, "somepage.html", {'to': to, 'from': ffrom})
而不是像
http://localhost/web/move?from=./here.py&to=../mydir
我明白了
http://localhost/web/move?from={{from}}&to={{to}}
这些上下文变量根本没有得到渲染,可能是因为自定义标记(应用于somepage
视图)将所有参数都作为字符串。如何强制首先渲染它?
感谢。
**编辑**小问题: 如果我想实现这个目标
url(r"^search/<?P(cbid)\d+>/", 'views.search', name='search')
如果我把它放在模板
中,我会得到Malformed arguments to query_urls tag
<a href={% query_url 'search' 12456 from=from to=to %}> MY LINK </a>
编写自定义标记的通用方法是什么?
目前,这就是我做的......哪个有效...
def render(self, context):
view_name = self.view_name.resolve(context)
kwargs = dict([(smart_str(k, 'ascii'), v.resolve(context))
for k, v in self.kwargs.items()])
cbid = kwargs['cbid']
kwargs = sorted(kwargs.items(), key=lambda x:x[0]) # sorted and generate a list of 2-tuple
# kwargs query set now contains no cbid
kwargs = [ value for index, value in enumerate(kwargs) if value[0] != 'cbid']
#raise AssertionError(urllib.urlencode(kwargs))
return (reverse(view_name, args=[(cbid),], current_app=context.current_app)
+ '?' + urllib.urlencode(kwargs))
我想让它更通用,匹配任何模式,而不仅仅是cbid。
<a href={% query_url 'search' cbid=12456 from=from to=to %}> MY LINK </a>
一种愚蠢的方式(也许唯一的方法)就是在模板中写出这样的东西
{% query_url 'view_func' args=[(cbid, some_text, more_text,)], from=foo to=bar %}
其中args在字面上被视为args列表,就像在常规python函数中一样。我们可能会eval
将其放入列表而不是文字字符串。
答案 0 :(得分:2)
我认为您调用的query_url
模板标记是answer you linked to中的myurl
标记。该模板标记不会针对模板上下文解析其参数。这是您可能尝试的更完整的实现,它还执行reverse
查找以获取将查询参数附加到的URL。
在Django 1.4中,这是对the simple_tag
decorator:
from django import template
register = template.Library()
@register.simple_tag
def query_url(view_name, **kwargs):
"""
Returns an absolute URL matching given view, with query parameters
appended. For example, if you have this URL in your configuration:
('^search/$', 'myapp.search')
then in a template you can create a search link like this:
{% query_url 'myapp.search' q=value1 id=value2 %}
The first argument is a path to a view. The other arguments become
query parameters, so the URL will look something like:
``/search/?q=querystring&id=123``.
"""
return reverse(view_name) + '?' + urllib.urlencode(kwargs)
但是在Django 1.3中你必须详细拼写:
from django import template
from django.core.urlresolvers import reverse
from django.template import Library, Node, TemplateSyntaxError
from django.utils.encoding import smart_str
import re
import urllib
register = template.Library()
class QueryURLNode(Node):
def __init__(self, view_name, kwargs):
self.view_name = view_name
self.kwargs = kwargs
def render(self, context):
view_name = self.view_name.resolve(context)
kwargs = dict([(smart_str(k, 'ascii'), v.resolve(context))
for k, v in self.kwargs.items()])
return (reverse(view_name, current_app=context.current_app)
+ '?' + urllib.urlencode(kwargs))
@register.tag
def query_url(parser, token):
"""
Returns an absolute URL matching given view, with query parameters
appended. For example, if you have this URL in your configuration:
('^search/$', 'myapp.search')
then in a template you can create a search link like this:
{% query_url 'myapp.search' q=object.name id=object.id %}
The first argument is a path to a view. The other arguments become
query parameters, so the URL will look something like:
``/search/?q=name&id=123``.
"""
bits = token.split_contents()
if len(bits) < 2:
raise TemplateSyntaxError("'%s' takes at least one argument"
" (path to a view)" % bits[0])
viewname = parser.compile_filter(bits[1])
kwargs = {}
kwarg_re = re.compile(r"(\w+)=(.+)")
for bit in bits[2:]:
match = kwarg_re.match(bit)
if not match:
raise TemplateSyntaxError("Malformed arguments to %s tag" % bits[0])
name, value = match.groups()
kwargs[name] = parser.compile_filter(value)
return QueryURLNode(viewname, kwargs)
答案 1 :(得分:1)
问题是您没有在自定义标记中解析上下文变量。