не может разрешить вызываемую переменную контекста - PullRequest
3 голосов
/ 28 июля 2011

пожалуйста, посмотрите на код ниже.Я пытаюсь сохранить лямбда-выражение в контекстной переменной и извлечь его из моего пользовательского тега шаблона.но поиск переменной возвращает пустую строку вместо лямбды, которую я ожидал.Зачем?любая идея?

спасибо

Константин

>>> c = dict(f = lambda x : 'x=%s' % x) >>> c['f'] <function <lambda> at 0x02D7FFB0> >>> template.Variable('f').resolve(c) '' >>>

Ответы [ 3 ]

2 голосов
/ 05 августа 2011

Передача лямбд в шаблон в Django 1.2.4 работала нормально, после обновления моего кода до Django 1.3 я тоже столкнулся с этой проблемой.Я перестал пытаться установить флаг alters_data и попытался применить патч в билете 15791, который также добавляет флаг do_not_call_in_templates (очевидно, слился в версии dev).То, как я обошел проблему до тех пор, пока не было найдено правильное решение, заключалось в том, чтобы использовать фабричную функцию без аргументов, которые возвращали лямбду, вместо передачи лямбды в шаблон.

def return_a_lambda():
    return lambda x : 'x=%s' % x

c = dict(f=return_a_lambda)
>>> c['f']
<function return_l at 0x33bc668>
template.Variable('f').resolve(c)
<function <lambda> at 0x33ccaa0>

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

https://docs.djangoproject.com/en/dev/ref/templates/api/ в разделе «Рендеринг контекста»

Обновление: AМногоразовый хак будет фабричной функцией, которая возвращает фабричную функцию:

def encapsulate(func):
    def wrapper():
        return func
    return wrapper

или более короткую версию:

def encapsulate(func):
    return lambda: func

с окончательным кодом, похожим на это:

c = dict(f=encapsulate(lambda x : 'x=%s' % x))

что легче интерпретировать.В моем случае (https://github.com/rosarior/mayan) Теперь мне нужно сделать это примерно 30 раз, чтобы запустить код в Django 1.3: '(

1 голос
/ 28 июля 2011

вот билет, который я нашел (который я только что открыл, потому что нашел, я думаю, «лучшее» решение): https://code.djangoproject.com/ticket/15791

0 голосов
/ 28 июля 2011

Странно, у меня это работает (используя Django 1.3):

In [9]: from django import template
In [10]: c = dict(f = lambda x : 'x=%s' % x)

In [11]: c['f']
Out[11]: <function <lambda> at 0x00F9D670>

In [12]: template.Variable('f').resolve(c)
Out[12]: <function <lambda> at 0x00F9D670>

Но из любопытства, зачем использовать dict вместо django.template.context.Context?

In [19]: c = django.template.context.Context()

In [21]: c['f'] = lambda x: 'x=%s' % x

In [22]: template.Variable('f').resolve(c)
Out[22]: <function <lambda> at 0x01946730>

(я бы оставил это как комментарий, но у меня еще недостаточно представителей).

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