Как я могу применить I18N к меткам CheckboxSelectMultiple в Django?

Учитывая приложение Django, я должен применить I18N к значениям, хранящимся в таблице «Площадь». Значения поля i18n_code указывают на записи msgid в моей локали/en_US/LC_MESSAGES/django.po.

Как вы можете видеть в моем коде, модель Startup имеет поле ManyToMany для Area. В моей форме область — это виджет CheckboxSelectMultiple. Как я могу получить внутри моего form01.html (шаблон) i18n_code, перейти к {% trans area.i18n_code %}, чтобы я мог получить параметры, отображаемые на правильном языке?

Я проверил много вопросов по этой теме... но не нашел четкого решения.

Оформить коды:

models.py:

@python_2_unicode_compatible
class Area (models.Model):
    name = models.CharField(max_length = 200)
    i18n_code = models.CharField(max_length = 200)
    def __str__(self):
        return self.name

@python_2_unicode_compatible
class Startup (models.Model):
    name = models.CharField(max_length = 200)
    # ...
    areas = models.ManyToManyField(Area, verbose_name = 'Areas')
    def __str__(self):
        return self.name

form01.html

<div class="row linhaForm">
    <div class="col-lg-4 legenda">
        <b>{% trans 'FORM_1_LABEL_AREA' %}</b>
        <p>{% trans 'FORM_1_LABEL_AREA_DESCRIPTION' %}</p>
    </div>
    <div class="col-lg-8">
        {% for area in form.areas %}
            <div class="checkbox">
                {{area}} <-------------------- Here is my problem!
            </div>
        {% endfor %}
    </div>
</div>

forms.py

from django.utils.translation import ugettext_lazy as _

class Step1Form(forms.ModelForm):
    class Meta:
        model = models.Startup
        fields = ['name', 'areas']
        widgets = {
            'areas': forms.CheckboxSelectMultiple(attrs={'onclick':'onAreaCheckHandler()'}),
            'name': forms.TextInput(attrs={'class': 'form-control'}),
        }
        error_messages = {
            'name': {
                'required': _("FORM_1_ERROR_NAME_REQUIRED")
            },
            'areas': {
                'required': _("FORM_1_ERROR_AREA_REQUIRED")
            }

        }
    def __init__(self, *args, **kwargs):
        super(Step1Form, self).__init__(*args, **kwargs)
        if self.instance:
            self.fields['areas'].queryset = models.Area.objects.all()

Если вы поможете мне с этим сценарием, поможете и с другим, который у меня есть, где я получил CharField с вариантами выбора и поля ForeignKey, отображаемые в теге Select.


person lordshark    schedule 13.02.2017    source источник


Ответы (2)


Я считаю, что это решит вашу проблему.

{% for area in form.fields.areas.queryset %}
    <div class="checkbox">
        {% trans area.i18n_code %}
    </div>
{% endfor %}
person Blackeagle52    schedule 13.02.2017
comment
Спасибо Blackeagle52! Вы действительно решили мою проблему! Мне придется написать больше кода... но у меня есть домен над ним. Я хотел бы иметь что-то более управляемое... создание виджетов или что-то в этом роде. Пока воспользуюсь вашим решением. Если я доберусь до чего-то внутри класса ModelForm... я опубликую здесь! - person lordshark; 13.02.2017

Я отвечаю на свой вопрос, чтобы показать вам свое решение после помощи Blackeagle52! (Я подумал... Это было похоже на программирование PHP или ASP в 2004 году.)

Для полей с набором запросов и виджетом CheckBoxSelectMultiple:

{% for area in form.fields.areas.queryset %}
    <div class="checkbox">
        <label for="id_areas_{{area.id}}">
            <input id="id_areas_{{area.id}}" name="areas" type="checkbox" value="{{area.id}}" {% if area.id in form.areas.value %} checked="checked" {% endif %}>
            {% trans area.i18n_code %}
        </label>
    </div>
{% endfor %}

Для полей с параметром choices (кортеж из 2 значений) и виджетом Select:

<select class="form-control" id="id_type_register" name="type_register">
    {% for type in form.fields.type_register.choices %}
        <option value="{{type.0}}" {% if type.0 == form.type_register.value %} selected="selected" {% endif %}>
            {% trans type.1 %}
        </option>
    {% endfor %}
</select>

В обоих случаях, если необходимо, просто измените queryset на choices и укажите свойства модели (например, имя, i18n_code, slug...) для отображения. В случае таких кортежей, как [('1', 'One'), ('2', 'Two'), ('3', 'Three')], свойства модели будут заменены на .0 или .1 после имени объявленной переменной в операторе for.

person lordshark    schedule 14.02.2017
comment
Действительно, таким образом вы можете перебрать свой выбор. Вы можете сделать for value, label in ... для удобочитаемости. Также обратите внимание на .value, так как у вас могут быть некоторые странные вещи, такие как целые числа и строки. - person Blackeagle52; 14.02.2017