Использование форм с django-translated-fields

#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).

Я хочу уточнить, что желаемое определение не такое, как указано выше. Желаемое определение — использовать текущий язык в форме и не всегда английский. Использование английского, когда текущий язык не является английским, является ошибкой.

Вы можете увидеть код здесь:

дерево

forms.py

models.py

Проблема прямо сейчас заключается в классе 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),
        }
  

Вы можете увидеть обновленный класс по этой ссылке.