diff options
| -rw-r--r-- | AUTHORS | 1 | ||||
| -rw-r--r-- | django/template/base.py | 4 | ||||
| -rw-r--r-- | docs/releases/2.0.6.txt | 3 | ||||
| -rw-r--r-- | tests/template_tests/templatetags/custom.py | 8 | ||||
| -rw-r--r-- | tests/template_tests/test_custom.py | 5 |
5 files changed, 18 insertions, 3 deletions
@@ -708,6 +708,7 @@ answer newbie questions, and generally made Django that much better: ryankanno Ryan Kelly <ryan@rfk.id.au> Ryan Niemeyer <https://profiles.google.com/ryan.niemeyer/about> + Ryan Rubin <ryanmrubin@gmail.com> Ryno Mathee <rmathee@gmail.com> Sam Newman <http://www.magpiebrain.com/> Sander Dijkhuis <sander.dijkhuis@gmail.com> diff --git a/django/template/base.py b/django/template/base.py index 6572eae8ab..a90f8bfdd9 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -51,7 +51,7 @@ times with multiple contexts) import logging import re -from inspect import getcallargs, getfullargspec +from inspect import getcallargs, getfullargspec, unwrap from django.template.context import ( # NOQA: imported for backwards compatibility BaseContext, Context, ContextPopException, RequestContext, @@ -712,7 +712,7 @@ class FilterExpression: # First argument, filter input, is implied. plen = len(provided) + 1 # Check to see if a decorator is providing the real function. - func = getattr(func, '_decorated_function', func) + func = unwrap(func) args, _, _, defaults, _, _, _ = getfullargspec(func) alen = len(args) diff --git a/docs/releases/2.0.6.txt b/docs/releases/2.0.6.txt index 659c3533e7..5d401a7ea9 100644 --- a/docs/releases/2.0.6.txt +++ b/docs/releases/2.0.6.txt @@ -9,4 +9,5 @@ Django 2.0.6 fixes several bugs in 2.0.5. Bugfixes ======== -* ... +* Fixed a regression that broke custom template filters that use decorators + (:ticket:`29400`). diff --git a/tests/template_tests/templatetags/custom.py b/tests/template_tests/templatetags/custom.py index 2e2ccf3782..45acd9655e 100644 --- a/tests/template_tests/templatetags/custom.py +++ b/tests/template_tests/templatetags/custom.py @@ -3,6 +3,7 @@ import operator from django import template from django.template.defaultfilters import stringfilter from django.utils.html import escape, format_html +from django.utils.safestring import mark_safe register = template.Library() @@ -14,6 +15,13 @@ def trim(value, num): @register.filter +@mark_safe +def make_data_div(value): + """A filter that uses a decorator (@mark_safe).""" + return '<div data-name="%s"></div>' % value + + +@register.filter def noop(value, param=None): """A noop filter that always return its first argument and does nothing with its second (optional) one. diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py index b37b5f8f1e..dbc5bc267d 100644 --- a/tests/template_tests/test_custom.py +++ b/tests/template_tests/test_custom.py @@ -25,6 +25,11 @@ class CustomFilterTests(SimpleTestCase): "abcde" ) + def test_decorated_filter(self): + engine = Engine(libraries=LIBRARIES) + t = engine.from_string('{% load custom %}{{ name|make_data_div }}') + self.assertEqual(t.render(Context({'name': 'foo'})), '<div data-name="foo"></div>') + class TagTestCase(SimpleTestCase): |
