2012-03-15 2 views
1

Ссылка: 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 просмотров) принимает все параметры в виде строки. Как заставить ее сначала отображать?

Спасибо.


** EDIT ** Маленький вопрос: Если я хочу, чтобы достичь этого

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 %} 

где арг берется буквально как список аргументов так же, как в обычной функции питона , Вероятно, это может быть eval в список, а не буквальную строку.

+1

Там нет необходимости для '{{}}' в шаблоне тега: вы должны просто написать '{% query_urls от = от = до%}' –

+0

@GarethRees Спасибо. Я просто попробовал. Это не работает. Это дает мне 'from = from & to = to' – User007

+1

А, я вижу: вы используете тег шаблона' myurl' из вопроса, с которым вы связались. Это не делает переменную оценку. Я напишу подробный ответ. –

ответ

2

Я предполагаю, что query_url шаблонный тег вы вызываете это myurl тег из answer you linked to. Этот тег шаблона не разрешает его аргументы в контексте шаблона. Вот более полная реализация, которую вы можете попробовать, а также поиск 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) 
+0

+1 для приятной демонстрации! – CppLearner

+0

Спасибо. Почему мы используем 'parser.compile_filter' ?? Что это делает? Благодарю. – User007

+1

Он создает объект ['FilterExpression'] (https://code.djangoproject.com/browser/django/trunk/django/template/base.py#L507), который« анализирует токен переменной и его дополнительные фильтры ». Таким образом, вы можете использовать фильтры шаблонов для аргументов в теге: '{% query_url 'myapp.view' a = var | upper b = var | truncatechars: 10%}' или что-то еще. –