将表单与django-translated-fields配合使用

时间:2019-03-29 14:28:29

标签: python django python-3.x

请查看以下问题:

How do I use ModelForm with django-translated-fields?

你有什么解决办法吗?

简而言之,我正在尝试将Speedy Net从使用django-modeltranslation转换为django-translated-fields。我定义了模型和表单,并且所有内容都以英语运行,但是使用另一种语言(希伯来语)时,我遇到了一个问题,即表单字段是用英语而不是希伯来语(当前语言)定义的。我做错了什么,如何定义以当前语言显示的表单? (在模型中,由TranslatedField定义的字段仅在使用SpeedyMatchProfileActivationForm形式的当前语言时才可见)。

我想澄清一下,所需的定义不是上面的定义。所需的定义是使用表格中的当前语言,而不总是使用英语。在当前语言不是英语的情况下使用英语是一个错误。

您可以在此处查看代码:

tree

forms.py

models.py

现在的问题是类SpeedyMatchProfileActivationForm(在forms.py中定义)。我认为主要是因为该类是在get_language()返回任何内容之前定义的。但是,当用django-modeltranslation定义类时(例如在分支staging中),它就起作用了。

顺便说一句,我要切换到django-translated-fields的原因之一是因为它在数据库中仅定义了2个(语言的数量)字段,而django-modeltranslation定义了3个字段-其中之一在我看来,它们(没有任何语言的主要领域)根本没有必要。看一眼: Remove original language field on migrations

class SpeedyMatchProfileActivationForm现在已定义(使用django-translated-fieldslink):

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-modeltranslationlink):

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 个答案:

答案 0 :(得分:0)

我找到了解决方案。这不是最佳解决方案,但可以。我将所有语言的字段都添加到了表单中。我们不需要的字段已在__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),
        }

您可以在此link中看到更新的课程。