#python #django #python-3.x #django-translated-fields
#python #django #python-3.x #django-translated-fields
Вопрос:
Пожалуйста, взгляните на эту проблему:
Как мне использовать ModelForm с django-translated-fields?
Есть ли у вас какое-либо решение?
Короче говоря, я пытаюсь преобразовать Speedy Net из using django-modeltranslation
в django-translated-fields
. Я определил модели и формы, и все работает на английском, но на другом языке (иврите) У меня проблема в том, что поля формы определены на английском, а не на иврите (текущий язык). Что я сделал не так и как мне определить форму для работы на текущем языке? (поля, определенные TranslatedField в модели, должны быть видны только на текущем языке в форме SpeedyMatchProfileActivationForm).
Я хочу уточнить, что желаемое определение не такое, как указано выше. Желаемое определение — использовать текущий язык в форме и не всегда английский. Использование английского, когда текущий язык не является английским, является ошибкой.
Вы можете увидеть код здесь:
Проблема прямо сейчас заключается в классе SpeedyMatchProfileActivationForm
(определенном в forms.py ). Я думаю, это главным образом потому, что класс определяется до того, get_language()
как что-либо возвращает. Но когда класс был определен с помощью django-modeltranslation
(например, в промежуточной ветке), это сработало.
Кстати, одна из причин, по которой я хочу переключиться на django-translated-fields
, заключается в том, что он определяет только 2 поля (количество языков) в базе данных и django-modeltranslation
определяет 3 поля — одно из них (основное поле без какого-либо языка) кажется мне совсем не нужным. Взгляните на: Удалить поле исходного языка при миграции
class SpeedyMatchProfileActivationForm
теперь определено (с помощью django-translated-fields
, ссылки):
class SpeedyMatchProfileActivationForm(forms.ModelForm):
validators = {
'height': [speedy_match_accounts_validators.validate_height],
'smoking_status': [speedy_match_accounts_validators.validate_smoking_status],
'marital_status': [speedy_match_accounts_validators.validate_marital_status],
to_attribute(name='profile_description'): [speedy_match_accounts_validators.validate_profile_description],
to_attribute(name='city'): [speedy_match_accounts_validators.validate_city],
to_attribute(name='children'): [speedy_match_accounts_validators.validate_children],
to_attribute(name='more_children'): [speedy_match_accounts_validators.validate_more_children],
to_attribute(name='match_description'): [speedy_match_accounts_validators.validate_match_description],
'gender_to_match': [speedy_match_accounts_validators.validate_gender_to_match],
'min_age_match': [speedy_match_accounts_validators.validate_min_age_match],
'max_age_match': [speedy_match_accounts_validators.validate_max_age_match],
'diet_match': [speedy_match_accounts_validators.validate_diet_match],
'smoking_status_match': [speedy_match_accounts_validators.validate_smoking_status_match],
'marital_status_match': [speedy_match_accounts_validators.validate_marital_status_match],
}
diet = forms.ChoiceField(choices=User.DIET_VALID_CHOICES, widget=forms.RadioSelect(), label=_('My diet'), validators=[speedy_match_accounts_validators.validate_diet])
photo = forms.ImageField(required=False, widget=CustomPhotoWidget, label=_('Add profile picture'))
class Meta:
model = SpeedyMatchSiteProfile
fields = ('photo', to_attribute(name='profile_description'), to_attribute(name='city'), 'height', to_attribute(name='children'), to_attribute(name='more_children'), 'diet', 'smoking_status', 'marital_status', 'gender_to_match', to_attribute(name='match_description'), 'min_age_match', 'max_age_match', 'diet_match', 'smoking_status_match', 'marital_status_match')
widgets = {
'smoking_status': forms.RadioSelect(),
'marital_status': forms.RadioSelect(),
to_attribute(name='profile_description'): forms.Textarea(attrs={'rows': 3, 'cols': 25}),
to_attribute(name='city'): forms.TextInput(),
to_attribute(name='children'): forms.TextInput(),
to_attribute(name='more_children'): forms.TextInput(),
to_attribute(name='match_description'): forms.Textarea(attrs={'rows': 3, 'cols': 25}),
'diet_match': CustomJsonWidget(choices=User.DIET_VALID_CHOICES),
'smoking_status_match': CustomJsonWidget(choices=SpeedyMatchSiteProfile.SMOKING_STATUS_VALID_CHOICES),
'marital_status_match': CustomJsonWidget(choices=SpeedyMatchSiteProfile.MARITAL_STATUS_VALID_CHOICES),
}
Это было ранее определено (с помощью django-modeltranslation
, ссылки):
class SpeedyMatchProfileActivationForm(TranslationModelForm):
validators = {
'height': [speedy_match_accounts_validators.validate_height],
'min_age_match': [speedy_match_accounts_validators.validate_min_age_match],
'max_age_match': [speedy_match_accounts_validators.validate_max_age_match],
'smoking_status': [speedy_match_accounts_validators.validate_smoking_status],
'city': [speedy_match_accounts_validators.validate_city],
'marital_status': [speedy_match_accounts_validators.validate_marital_status],
'children': [speedy_match_accounts_validators.validate_children],
'more_children': [speedy_match_accounts_validators.validate_more_children],
'profile_description': [speedy_match_accounts_validators.validate_profile_description],
'match_description': [speedy_match_accounts_validators.validate_match_description],
'gender_to_match': [speedy_match_accounts_validators.validate_gender_to_match],
'diet_match': [speedy_match_accounts_validators.validate_diet_match],
'smoking_status_match': [speedy_match_accounts_validators.validate_smoking_status_match],
'marital_status_match': [speedy_match_accounts_validators.validate_marital_status_match],
}
diet = forms.ChoiceField(choices=User.DIET_VALID_CHOICES, widget=forms.RadioSelect(), label=_('My diet'), validators=[speedy_match_accounts_validators.validate_diet])
photo = forms.ImageField(required=False, widget=CustomPhotoWidget, label=_('Add profile picture'))
class Meta:
model = SpeedyMatchSiteProfile
fields = ('photo', 'profile_description', 'city', 'height', 'children', 'more_children', 'diet', 'smoking_status', 'marital_status', 'gender_to_match', 'match_description', 'min_age_match', 'max_age_match', 'diet_match', 'smoking_status_match', 'marital_status_match')
widgets = {
'profile_description': forms.Textarea(attrs={'rows': 3, 'cols': 25}),
'children': forms.TextInput(),
'more_children': forms.TextInput(),
'smoking_status': forms.RadioSelect(),
'marital_status': forms.RadioSelect(),
'match_description': forms.Textarea(attrs={'rows': 3, 'cols': 25}),
'diet_match': CustomJsonWidget(choices=User.DIET_VALID_CHOICES),
'smoking_status_match': CustomJsonWidget(choices=SpeedyMatchSiteProfile.SMOKING_STATUS_VALID_CHOICES),
'marital_status_match': CustomJsonWidget(choices=SpeedyMatchSiteProfile.MARITAL_STATUS_VALID_CHOICES),
}
Спасибо!
Комментарии:
1. (Кстати, я пытался, но не могу добавить тег
django-translated-fields
)
Ответ №1:
Я нашел решение. Это не оптимальное решение, но оно работает. Я добавил в форму поля на всех языках. Поля, которые нам не нужны, уже удалены в __init__
методе.
class SpeedyMatchProfileActivationForm(forms.ModelForm):
validators = {
'height': [speedy_match_accounts_validators.validate_height],
'smoking_status': [speedy_match_accounts_validators.validate_smoking_status],
'marital_status': [speedy_match_accounts_validators.validate_marital_status],
**{to_attribute(name='profile_description', language_code=language_code): [speedy_match_accounts_validators.validate_profile_description] for language_code, language_name in django_settings.LANGUAGES},
**{to_attribute(name='city', language_code=language_code): [speedy_match_accounts_validators.validate_city] for language_code, language_name in django_settings.LANGUAGES},
**{to_attribute(name='children', language_code=language_code): [speedy_match_accounts_validators.validate_children] for language_code, language_name in django_settings.LANGUAGES},
**{to_attribute(name='more_children', language_code=language_code): [speedy_match_accounts_validators.validate_more_children] for language_code, language_name in django_settings.LANGUAGES},
**{to_attribute(name='match_description', language_code=language_code): [speedy_match_accounts_validators.validate_match_description] for language_code, language_name in django_settings.LANGUAGES},
'gender_to_match': [speedy_match_accounts_validators.validate_gender_to_match],
'min_age_match': [speedy_match_accounts_validators.validate_min_age_match],
'max_age_match': [speedy_match_accounts_validators.validate_max_age_match],
'diet_match': [speedy_match_accounts_validators.validate_diet_match],
'smoking_status_match': [speedy_match_accounts_validators.validate_smoking_status_match],
'marital_status_match': [speedy_match_accounts_validators.validate_marital_status_match],
}
diet = forms.ChoiceField(choices=User.DIET_VALID_CHOICES, widget=forms.RadioSelect(), label=_('My diet'), validators=[speedy_match_accounts_validators.validate_diet])
photo = forms.ImageField(required=False, widget=CustomPhotoWidget, label=_('Add profile picture'))
class Meta:
model = SpeedyMatchSiteProfile
fields = (
'photo',
*(to_attribute(name='profile_description', language_code=language_code) for language_code, language_name in django_settings.LANGUAGES),
*(to_attribute(name='city', language_code=language_code) for language_code, language_name in django_settings.LANGUAGES),
'height',
*(to_attribute(name='children', language_code=language_code) for language_code, language_name in django_settings.LANGUAGES),
*(to_attribute(name='more_children', language_code=language_code) for language_code, language_name in django_settings.LANGUAGES),
'diet',
'smoking_status',
'marital_status',
'gender_to_match',
*(to_attribute(name='match_description', language_code=language_code) for language_code, language_name in django_settings.LANGUAGES),
'min_age_match',
'max_age_match',
'diet_match',
'smoking_status_match',
'marital_status_match',
)
widgets = {
'smoking_status': forms.RadioSelect(),
'marital_status': forms.RadioSelect(),
**{to_attribute(name='profile_description', language_code=language_code): forms.Textarea(attrs={'rows': 3, 'cols': 25}) for language_code, language_name in django_settings.LANGUAGES},
**{to_attribute(name='city', language_code=language_code): forms.TextInput() for language_code, language_name in django_settings.LANGUAGES},
**{to_attribute(name='children', language_code=language_code): forms.TextInput() for language_code, language_name in django_settings.LANGUAGES},
**{to_attribute(name='more_children', language_code=language_code): forms.TextInput() for language_code, language_name in django_settings.LANGUAGES},
**{to_attribute(name='match_description', language_code=language_code): forms.Textarea(attrs={'rows': 3, 'cols': 25}) for language_code, language_name in django_settings.LANGUAGES},
'diet_match': CustomJsonWidget(choices=User.DIET_VALID_CHOICES),
'smoking_status_match': CustomJsonWidget(choices=SpeedyMatchSiteProfile.SMOKING_STATUS_VALID_CHOICES),
'marital_status_match': CustomJsonWidget(choices=SpeedyMatchSiteProfile.MARITAL_STATUS_VALID_CHOICES),
}
Вы можете увидеть обновленный класс по этой ссылке.