В 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 doc по отношение на формуляри: [...] В допълнение, всяко генерирано поле на формуляр има атрибути, зададени както следва: • Ако полето за модел има blank=True, след което задължителният е зададен на False в полето на формуляра. В противен случай, задължително=Вярно. • Етикетът на полето на формуляра е зададен на verbose_name на полето на модела, като първият знак е с главна буква[...]. - person nolnol; 04.02.2014

Най-накрая намерих начин, използвайки работата, описана от Beau Simensen: 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