2đź‘Ť
Passing lambdas to the template in Django 1.2.4 worked fine, after upgrading my code to Django 1.3, I was bit by the same issue too. I gave up on trying to set alters_data flag and trying to apply the patch in ticket 15791 that adds a do_not_call_in_templates flag too (apparently merged in the dev version). The way I sidestepped the problem until a proper solution is in place was to use a factory function without arguments that returned the lambda instead of passing the lambda to the template.
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’s template calls all context variables as long as they don’t need an argument, hence return_a_lambda is executed and the template gets the lambda in return.
https://docs.djangoproject.com/en/dev/ref/templates/api/ under “Rendering a context”
Update:
A reusable hack would be a factory function that returns a factory function:
def encapsulate(func):
def wrapper():
return func
return wrapper
or a shorter version:
def encapsulate(func):
return lambda: func
with the final code looking like this:
c = dict(f=encapsulate(lambda x : 'x=%s' % x))
which is easier to interpret. In my case (https://github.com/rosarior/mayan) I now have to do this some 30 times aprox to get the code running in Django 1.3 :'(
1đź‘Ť
here is a ticket that I found (that I have just reopened because I have found, I think, a “better” solution): https://code.djangoproject.com/ticket/15791
- [Django]-Get all values from Django QuerySet plus additional fields from a related model
- [Django]-TypeError: add() argument after * must be a sequence, not Subscribers
- [Django]-Integer out of Range – Django
- [Django]-Render two views to a single html template
0đź‘Ť
Odd, it works for me (using 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>
But out of curiosity, why use a dict instead of a 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>
(I’d leave this as a comment but I don’t have quite enough rep yet).
- [Django]-Django {% static "admin/" %}' producing 'admin' with missing trailing slash in production ONLY
- [Django]-Changing django-storages backend from from s3 to cloudfiles and dealing with old files
- [Django]-Customize form brought from Django forms.py