Fixed #31154 -- Added support for using enumeration types in templates.

Enumeration helpers are callables, so the template system tried to call
them with no arguments.

Thanks Rupert Baker for helping discover this.
This commit is contained in:
Adam Johnson 2020-01-09 15:41:54 +00:00 committed by Mariusz Felisiak
parent 4c1b401e82
commit 5166097d7c
3 changed files with 10 additions and 0 deletions

View File

@ -31,6 +31,7 @@ class ChoicesMeta(enum.EnumMeta):
# that is passed in as "self" as the value to use when looking up the # that is passed in as "self" as the value to use when looking up the
# label in the choices. # label in the choices.
cls.label = property(lambda self: cls._value2label_map_.get(self.value)) cls.label = property(lambda self: cls._value2label_map_.get(self.value))
cls.do_not_call_in_templates = True
return enum.unique(cls) return enum.unique(cls)
def __contains__(cls, member): def __contains__(cls, member):

View File

@ -20,3 +20,6 @@ Bugfixes
* Relaxed the system check added in Django 3.0 to reallow use of a sublanguage * Relaxed the system check added in Django 3.0 to reallow use of a sublanguage
in the :setting:`LANGUAGE_CODE` setting, when a base language is available in in the :setting:`LANGUAGE_CODE` setting, when a base language is available in
Django but the sublanguage is not (:ticket:`31141`). Django but the sublanguage is not (:ticket:`31141`).
* Added support for using enumeration types ``TextChoices``,
``IntegerChoices``, and ``Choices`` in templates (:ticket:`31154`).

View File

@ -4,6 +4,7 @@ import ipaddress
import uuid import uuid
from django.db import models from django.db import models
from django.template import Context, Template
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.utils.functional import Promise from django.utils.functional import Promise
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -149,6 +150,11 @@ class ChoicesTests(SimpleTestCase):
with self.subTest(member=member): with self.subTest(member=member):
self.assertEqual(str(test[member.name]), str(member.value)) self.assertEqual(str(test[member.name]), str(member.value))
def test_templates(self):
template = Template('{{ Suit.DIAMOND.label }}|{{ Suit.DIAMOND.value }}')
output = template.render(Context({'Suit': Suit}))
self.assertEqual(output, 'Diamond|1')
class Separator(bytes, models.Choices): class Separator(bytes, models.Choices):
FS = b'\x1c', 'File Separator' FS = b'\x1c', 'File Separator'