Django – How to translate static choices of a form field

I have a form to update the details of the user in a multilingual text. In the dropdown for sex, it does not translate the choice of sex as below:

Example

I tried using the gettext_noop in the model.py file for the choices. I see them in the .po file. Still it doesn’t work. What am I doing wrong?

model.py

from django.utils.translation import gettext_noop
Account_sex = [('male',gettext_noop('Male')),('female',gettext_noop('Female'))]  #List of tuples with choices. First one is what's stored in DB and second what is shown in html.

class Account(AbstractBaseUser):
    first_name = models.CharField(max_length=50)
    email = models.EmailField(max_length=100, unique=True)
    sex = models.CharField(max_length=10, blank=True, null=True, choices=Account_sex, default="male") 

view.py

@login_required(login_url="login")
def edit_profile(request):
    if request.user.is_authenticated:
        current_user = Account.objects.get(id=request.user.id)
        form = EditProfileForm(request.POST or None, instance=current_user)
        if form.is_valid():
            form.save()
            messages.success(request,("Your profile has been updated!"))
            return redirect('dashboard')

        return render(request, 'accounts/edit_profile.html',context={'form':form}) #
    else:
        messages.success(request,('You must be logged in!'))
        return redirect('login')

edit_profile.html

<div class="col col-auto form-group">
 <label>{% trans "Sex" %}</label>
 {{ form.sex }}
</div>

django.po

#: .\accounts\models.py:44
msgid "Male"
msgstr "Hombre"

#: .\accounts\models.py:44
msgid "Female"
msgstr "Mujer"

The simple answer is you need to use gettext_lazy instead of gettext_noop.

gettext_noop says “This is a translatable string” for the purpose of .po files etc, but doesn’t actually translate it. This is useful if you need to use, for example, the translated string in a user message, but the untranslated string in a log. But you’ll need to use gettext_lazy to actually translate it (using the lazy version here to defer translation until the user-chosen language is known).

Leave a Comment