How to add labels for Django models.IntegerChoices
Asked Answered
T

2

5

I have two IntegerChoices subclasses in one of my django Models that define ticket priorities for an api. I would like when the priority and statuses are rendered on my web page to show the label, but then when using the api to send the integer number corresponding with the label. This is my code so far:

class Ticket(models.Model):
    class Statuses(models.IntegerChoices):
        OPEN = 2, 'Open'
        PENDING = 3, 'Pending'
        RESOLVED = 4, 'Resolved'
        CLOSED = 5, 'Closed'
    class Priorities(models.IntegerChoices):
        LOW = 1, 'Low'
        MEDIUM = 2, 'Medium'
        HIGH = 3, 'High'
        URGENT = 4, 'Urgent'
    
    priority = models.IntegerField(default=Priorities.LOW, choices=Priorities.choices)
    status = models.IntegerField(default=Statuses.OPEN, choices=Statuses.choices)

I then try to access the label in my application via

<b>Priority: </b> {{ ticket.priority.label }} <br>
<b>Status:</b> {{ ticket.status.label }}

But nothing shows up. It seems the Django docs for the new IntegerChoices class is very minimal, and is not clear about how the labeling function works.

I also tried rendering the labels like so:

OPEN = 2, _('Open')

But then I got an error saying "name '_' is undefined"

Any pointers in the right direction for what I need to do?

UPDATE

For anyone who needs the answer, I figured it out.

I realized that the error for rendering the labels was due to not having this line imported at the start of my models:

from django.utils.translation import gettext_lazy as _

from there on, in order to access the labels from the template I implemented 2 get functions in my ticket model

def get_status(self):
    return self.Statuses(self.status).label
def get_priority(self):
    return self.Priorities(self.priority).label

and then to grab them in the template you do this:

<div>
{{ ticket.get_priority }}<br>
{{ ticket.get_status }}
</div>
Targe answered 2/9, 2020 at 17:43 Comment(0)
A
11

No need to add the functions to fetch the labels. Using the get_FOO_display method works fine. So in your case, on the template you would use {{ ticket.get_priority_display }} to get the "human-readable" value. See docs.

Afflict answered 21/9, 2020 at 1:33 Comment(0)
L
2

If you want to get the human-readable text inside Python, you have to call the get_FOO_display() method with parentheses.

In the context of an f-string this would be e.g.:

f"Priority: {self.get_priority_display()}, Status: {self.get_status_display()}"
Lustig answered 14/6, 2023 at 12:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.