Почему моя переменная контекста не отрисовалась правильно - PullRequest
1 голос
/ 16 марта 2012

Ссылка: Как создать реверс / URL Django, используя аргументы запроса?

Это в 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 воспринимается буквально как список аргументов, как в обычной функции python. Возможно, мы можем eval сделать это в виде списка вместо буквальной строки.

Ответы [ 2 ]

2 голосов
/ 16 марта 2012

Я предполагаю, что вызываемый вами шаблонный тег query_url является тегом myurl из ответа , с которым вы связались . Этот тег шаблона не разрешает свои аргументы против контекста шаблона. Вот более полная реализация, которую вы можете попробовать, которая также выполняет поиск reverse, чтобы получить URL-адрес для добавления аргументов запроса.

В Django 1.4 это прямое использование simple_tag декоратора :

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 голос
/ 16 марта 2012

Проблема в том, что вы не разрешили переменную контекста в вашем пользовательском теге.

Читать это: Передача переменной шаблона в тег

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...