В Django, в форме, как динамически выбирать пользовательское поле модели для отображения в ModelChoiceField?

Мне нужно управлять записями на разных языках, с контентом, редактируемым онлайн зарегистрированными пользователями, без использования инструмента администрирования Django.

Формы должны быть локализованы на каждом языке.

Поскольку количество языков фиксировано, я решил обрабатывать разные языки с разными полями в модели, с именем поля, дополненным кодом языка, см. пример ниже.

# models.py
class MyAttribute(models.Model):
    name_en = models.CharField()     # name in English
    name_es = models.CharField()     # name in Spanish
    name_fr = models.CharField()     # name in French
    field2_en = models.CharField()   # field2 in English
    field2_es = models.CharField()   # field2 in Spanish
    field2_fr = models.CharField()   # field2 in French

class MyGroup(models.Model):
    name_en = models.CharField()     # name in English
    name_es = models.CharField()     # name in Spanish
    name_fr = models.CharField()     # name in French
    myattribute = models.ForeignKey(MyAttribute)

Я уже создал собственный тег для отображения локализованного контента в моих шаблонах, и он работает хорошо.

{% localized_value mygroup name current_language %}

Теперь мне нужно настроить форму для редактирования объектов MyGroup с полем models.ModelChoiceField для поля myattribute. Насколько я понимаю, по умолчанию всегда будет отображаться одна и та же строка, сгенерированная label_from_instance() в модели, и нет возможности использовать там request.LANGUAGE_CODE.

Итак, мой вопрос: как динамически выбирать правильное поле name_language_code для отображения в моей форме?

Реализация может быть примерно такой:

# views.py    
form.fields["myattribute"].related_field = eval('name_' + language_code)

or

# template.html    
{{ form.myattribute language_code }}

Есть идеи?

Кстати, используя Django 1.6


person nolnol    schedule 03.02.2014    source источник


Ответы (2)


Чувак, если ты хочешь сделать перевод того, что известно как verbose_name, в идеале ты должен использовать интернационализацию django.

Документация по следующей ссылке: https://docs.djangoproject.com/en/dev/topics/i18n/translation/

person arannasousa    schedule 03.02.2014
comment
Спасибо за ваш быстрый отзыв. Потратил некоторое время на документацию Django и нашел информацию для локализации: текст в шаблонах, имя и текст справки полей модели, способы переключения языка сеанса... но не нашел способов управлять разными значениями для одного и того же поля. Есть несколько приложений для I18N, но мне они показались излишними. Моя цель - динамически переключать поле, используемое для рендеринга объекта внешнего ключа, называемого ModelChoiceField. - person nolnol; 04.02.2014
comment
verbose_name позволяет переводить имена полей, но не их значения. Выдержка из документа Django относительно форм: [...] Кроме того, каждое сгенерированное поле формы имеет атрибуты, установленные следующим образом: • Если поле модели имеет пустое значение = True, тогда для поля формы required установлено значение False. В противном случае требуется = Истина. • В качестве метки поля формы задается подробное_имя поля модели, причем первый символ пишется с большой буквы[...]. - person nolnol; 04.02.2014

Наконец-то я нашел способ, используя работу, описанную Бо Сименсеном: http://srcmvn.com/blog/2013/01/15/django-advanced-model-choice-field/, который изменил ModelChoiceField для возврата (значение, метка, модель ) вместо (значение,метка).

Пока, кажется, работает нормально для меня.

from django.forms import models
from django.forms.fields import ChoiceField

class AdvancedModelChoiceIterator(models.ModelChoiceIterator):
    def choice(self, obj):
        return (self.field.prepare_value(obj), self.field.label_from_instance(obj), obj)

class AdvancedModelChoiceField(models.ModelChoiceField):
    def _get_choices(self):
        if hasattr(self, '_choices'):
            return self._choices

        return AdvancedModelChoiceIterator(self)

    choices = property(_get_choices, ChoiceField._set_choices)
person nolnol    schedule 04.02.2014