templates: add support for "in" and "not in" using a lazy left operand (#49958)

This commit is contained in:
Frédéric Péters 2021-01-16 22:06:43 +01:00
parent a63ca258a1
commit facedb66c8
2 changed files with 33 additions and 0 deletions

View File

@ -1521,6 +1521,20 @@ def test_lazy_conditions(pub, variable_test_data):
assert condition.evaluate() is True
def test_lazy_conditions_in(pub, variable_test_data):
condition = Condition({'type': 'django', 'value': 'form_var_foo_foo in "foo, bar, baz"'})
assert condition.evaluate() is True
condition = Condition({'type': 'django', 'value': 'form_var_foo_foo not in "foo, bar, baz"'})
assert condition.evaluate() is False
condition = Condition({'type': 'django', 'value': '"b" in form_var_foo_foo'})
assert condition.evaluate() is True
condition = Condition({'type': 'django', 'value': '"b" not in form_var_foo_foo'})
assert condition.evaluate() is False
def test_has_role_templatefilter(pub, variable_test_data):
condition = Condition({'type': 'django', 'value': 'form_user|has_role:"foobar"'})
assert condition.evaluate() is False

View File

@ -16,6 +16,7 @@
from quixote import get_publisher
from django.template import Context, Template, TemplateSyntaxError
import django.template.smartif
from django.utils.encoding import force_text
from .qommon import _, get_logger, force_str
@ -94,3 +95,21 @@ class Condition(object):
Template('{%% if %s %%}OK{%% endif %%}' % self.value)
except (TemplateSyntaxError, OverflowError) as e:
raise ValidationError(_('syntax error: %s') % force_str(force_text(e)))
# add support for "in" and "not in" operators with left operand being a lazy
# value.
def lazy_eval(context, x):
x = x.eval(context)
if hasattr(x, 'get_value'):
x = x.get_value()
return x
django.template.smartif.OPERATORS['in'] = django.template.smartif.infix(
django.template.smartif.OPERATORS['in'].lbp,
lambda context, x, y: lazy_eval(context, x) in y.eval(context))
django.template.smartif.OPERATORS['not in'] = django.template.smartif.infix(
django.template.smartif.OPERATORS['not in'].lbp,
lambda context, x, y: lazy_eval(context, x) not in y.eval(context))