2011-07-28 14 views
2

以下のコードをご覧ください。ラムダ式をコンテキスト変数に格納し、カスタムテンプレートタグでそれを取得しようとしています。変数ルックアップは、私が期待したラムダの代わりに空の文字列を返します。どうして?何か案が?呼び出し可能なコンテキスト変数を解決できません

おかげ

コンスタンチン

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

答えて

2

はうまく働いていました、私のコードをDjango 1.3にアップグレードした後、私も同じ問題が少しありました。私はalters_dataフラグを設定しようとしていて、do_not_call_in_templatesフラグも追加したチケット15791にパッチを適用しようとしました(明らかに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/

更新:

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/rosario/mayan)、Django 1.3でコードを実行するために、これを30回aproxで実行する必要があります: '(

+0

ありがとう。これは私が使用した回避策であり、私が私の答えで言及したチケットでそれを言及しました。私はdjangoが最初にcallable context variabesをなぜ呼び出すのだろうか?私はそれが私が文脈の中に入れたビジネスのどれでもないと言います。 :)しかし、これはdjango devのリストのための議論だと思う... – akonsu

+0

私はそれが今、私にも起こった 'ejucovy'に起こった、ファクトリー関数としてラムダを使用することは難読化されています。 –

+0

私はあなたに同意します、Changeset 16045は、存在してはいけない問題を '修正'することによって最悪のことを起こしています。テンプレートリゾルバは変数を呼び出そうとすべきではありません。 –

0

奇数、それは(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> 

しかし、好奇心のうち、なぜ代わりに辞書を使います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> 

(これはコメントとして残しておきますが、十分な担当者はまだいません)。ここ

+0

ありがとう。私のTEMPLATE_STRING_IF_INVALIDが設定されていないため、空文字列が返されます。 – akonsu

+0

私のコメントを少し編集し、設定についての部分を削除しました。 – sandinmyjoints

+0

djangoのドキュメントがdictを使用しているため – akonsu

0

は、私は(私が見つけたので、私はちょうど、私が思うに、「より良い」ソリューションをリニューアルオープンしたことを)見つけチケットです:Djangoの1.2.4でテンプレートにラムダを渡すhttps://code.djangoproject.com/ticket/15791

関連する問題