[Solved]-Django translate model choices


In models.py, you need to

from django.utils.translation import ugettext_lazy as _

ugettext_lazy will return a callable rather than the translated string. When the callable is evaluated later, it will return the translated string. It will be late enough that it will get the right language for the view/template processing.

See https://docs.djangoproject.com/en/dev/topics/i18n/translation/#lazy-translations.

This next part was not your question, but: in django you should use forms to process the user input, rather than accessing it directly from request.POST.get. That’s a whole other topic, but I could not let it go unaddressed in this answer, for fear someone else might use that method.


Here is an example for translating values that you save in your db.


from django.db import models
from django.utils.translation import gettext_noop

  ("choice one", gettext_noop("choice one")) # gettext_noop will mark the string to be translated when you later do "python3 manage.py makemessages"
  ("choice two", gettext_noop("choice two"))

class Foo(models.Model)
  category = models.CharField(choices=CATEGORY_CHOICES, max_length=50)

Just do python3 manage.py makemessages to generate the locale django.po files, enter the translations. And then do, python3 manage.py compilemessages to compile your locale files.

Now, at the time of returning this field from your views or api, just make sure to do this:


from django.utils.translation import ugettext as _

def get_category():
  foo = Foo.objects.get(id=1)
  return _(foo.category)


I think I’m late to the party but I’ve just resolved a similar problem. There’s a very good solution in the django documentation.

from django.utils.translation import gettext_lazy as _
class Student(models.Model):
    class YearInSchool(models.TextChoices):
        FRESHMAN = 'FR', _('Freshman')
        SOPHOMORE = 'SO', _('Soph*m*re')
        JUNIOR = 'JR', _('Junior')
        SENIOR = 'SR', _('Senior')
        GRADUATE = 'GR', _('Graduate')

    year_in_school = models.CharField(max_length=2, choices=YearInSchool.choices, default=YearInSchool.FRESHMAN,)



  1. Deploy enums (enums.py) within the app folder like so:


from enum import Enum, unique
from django.utils.translation import gettext_lazy as _
@unique class SomeChoice(Enum):
  first = _('First Option')
  second = _('Second Option')

Obviously, you’ll then import the enum into your model & use as needed.

name = models.CharField(max_length=30, db_index=True, choices=[(s.name, s.value) for s in SomeChoice])

At this stage, I’m assuming you’ve already written your locale files, so you have your .po files already set up.

#Append your translation content within .po | or via rosetta app

django-admin makemessages -all

django-admin compilemessages

Click the alternative language link




    ('LAB', 'labor'),
    ('CAR', 'cars'),
    ('TRU', 'trucks'),
    ('WRI', 'writing'),

class PostAd(models.Model):  
    name = models.CharField(max_length=50)
    email = models.EmailField()
    gist = models.CharField(max_length=50)
    category = models.CharField(max_length=3, choices=CATEGORIES)


    ('LAB', 'labor'),
    ('CAR', 'cars'),
    ('TRU', 'trucks'),
    ('WRI', 'writing'),

category = forms.ChoiceField(choices=CATEGORIES, required=True)


<!-- category -->
<div class="fieldWrapper">
    {{ form.category.errors }}
    <label for="id_category">Category</label>
    {{ form.category }}
<!-- location -->

Leave a comment