Search code examples
djangointernationalizationdjango-generic-views

Internationalizing a Django class-based generic view (CreateView)?


I am using Django 1.9 class-based generic views, for example CreateView. When I visit the "create" page, some parts are translated (into French in my example), so I know my config and wiring is correct, but the form fields (auto-named by the view) are not (i.e. form.as_p).

How can I get form fields to be used from my translations file? (For example, "Name" is a field, already translated, but not picked up by the form.as_p).

One answer is to list out the fields individually in the template with {% trans %} tags. I was hoping to avoid that.

My example is similar to the one in the docs, so let me repeat that example here. First, code:

from django.views.generic.edit import CreateView
from myapp.models import Author

class AuthorCreate(CreateView):
    model = Author
    fields = ['name']

Then display template:

<form action="" method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save" />
</form>

Solution

  • Have a look at the Lazy Translation:

    This is essential when calls to these functions are located in code paths that are executed at module load time.

    This is something that can easily happen when defining models, forms and model forms, because Django implements these such that their fields are actually class-level attributes.

    So, if you have a form, you can use ugettext_lazy to translate:

    from django.db import models
    from django.utils.translation import ugettext_lazy as _
    
    class MyThing(models.Model):
        name = models.CharField(help_text=_('This is the help text'))
    

    You can mark names of ForeignKey, ManyToManyField or OneToOneField relationship as translatable by using their verbose_name options:

    class MyThing(models.Model):
        kind = models.ForeignKey(
            ThingKind,
            on_delete=models.CASCADE,
            related_name='kinds',
            verbose_name=_('kind'),
        )