django-model-utils icon indicating copy to clipboard operation
django-model-utils copied to clipboard

Comparisons of Choices in Templates is broken

Open michel4j opened this issue 6 years ago • 4 comments

Problem

Given the following model,

class Document(TimeStampedModel):
    TYPE = Choices(
        ('snippet', _('A Snippet')),
        ('video', _('A Video')),
        ('image', _('An Image')),
    )
    kind = models.CharField(max_length=20, default=TYPE.snippet, choices=TYPE)

and an object with kind set to TYPE.video, the following template

{% if  guide.kind == guide.TYPE.video %}
MATCHED: "{{ guide.TYPE.video }}", "{{ guide.kind }}", "{{guide.get_kind_display}}"
{% else %}
NOT MATCHED: "{{ guide.TYPE.video }}", "{{ guide.kind }}", "{{guide.get_kind_display}}"
{% endif %}

produces the output:

NOT MATCHED: "A Video", "video", "A Video"

Expected output:

MATCHED: "video", "video", "A Video"

The problem appear to be due to the Django template system translating guide.TYPE.video into Guide.TYPE['video'] instead of directly using the attribute Guide.TYPE.video. This effectively renders useless, an important use case for the Choices -- avoiding magic strings in templates.

Environment

  • Django Model Utils version: 4.0.0
  • Django version: 3.0.1
  • Python version: 3.7.5

michel4j avatar Dec 31 '19 04:12 michel4j

I have the same error:

Environment

  • Django Model Utils version: 4.0.0
  • Django version: 2.1.15
  • Python version: 3.6.9

DmytroLitvinov avatar Mar 12 '20 15:03 DmytroLitvinov

I have the same error, why no body answer this issue? is it not maintened Choices for django models utils? :-)

sandrinesuire avatar Nov 27 '20 12:11 sandrinesuire

for waiting update, i create this solution

from model_utils import Choices as Choice

class Choices(Choice):
    def k(self):
        """
        Method returning dict with same key in key value to force key in template
        """
        return self._identifier_map

and after all my Choices come from my class

class TOTO(models.Model):
    MY_CHOICES = Choices(
        ("FIRST", "first blablabla"),
        ("SECOND", "second bla bla bla"),
    )

in template call choice with method "k" before

{{ object.MY_CHOICES.k.FIRST }}

sandrinesuire avatar Nov 27 '20 14:11 sandrinesuire

Same problem here, basically in the template method __getitem__ is called instead of __getattr__

viliammihalik avatar May 25 '22 09:05 viliammihalik