Question

I am using the same form and changing the choices.

All of the choices have a translation.

Do I need to specify something in the form?

forms.py

class QuestionForm(forms.Form):
    selection = forms.ChoiceField(widget=forms.RadioSelect())

views.py

from django.utils.translation import ugettext as _
form = QuestionForm(request.POST)
choices = [(_(i.choice), i.choice) for i in question.choices.all()]
form.fields['selection'].choices = choices

template

<form method="post">{% csrf_token %}
    {{ form.selection }}
    <input type="submit" value="Submit" class="btn"/>
</form>

I tried

{% trans form.selection %}

but got the error"

'BoundField' object has no attribute 'replace'
Était-ce utile?

La solution

(_(i.choice), i.choice) is in the wrong order, you won't see a translation. It's the second item that gets displayed, so you want to have: (i.choice, _(i.choice)).


Also, if you want a dynamic form, you should be creating a dynamic form using a form factory.

Do not play with the form internals after you've created it.

Somewhere in your code:

def make_question_form_class(question):
     choices = [(_(i.choice), i.choice) for i in question.choices.all()]

     class _QuestionForm(forms.Form):
         selection = forms.ChoiceField(choices = choices, widget=forms.RadioSelect())

     return _QuestionForm

In your view:

form_class = make_question_form_class(question)
form = form_class(request.POST)

See this post by James Bennett himself for more possibilities!

Autres conseils

The translation needs to occur at template rendering time. For this, you either need the proper language to be set when running (how to achieve this depends on the exact context the code is running in):

choices = [(_(i.choice), i.choice) for i in question.choices.all()]

Or instead use ugettext_lazy, which will not translate the choices, but defer translation until rendering time:

from django.utils.translation import ugettext_lazy as _
choices = [(_(i.choice), i.choice) for i in question.choices.all()]

In the template, always use:

<form method="post">{% csrf_token %}
    {{ form.selection }}
    <input type="submit" value="Submit" class="btn"/>
</form>

The form.selection object is a BoundField object and cannot be translated directly.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top