使用带有 django-translated-fields 的表单

Using forms with django-translated-fields

请看一下这个问题:

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

你有什么解决办法吗?

简而言之,我正在尝试将 Speedy Net 从使用 django-modeltranslation 转换为 django-translated-fields。我定义了模型和表单,一切都用英语工作,但在另一种语言(希伯来语)中我遇到了一个问题,即表单字段是用英语而不是希伯来语(当前语言)定义的。我做错了什么以及如何定义表格以在当前语言中工作? (模型中由 TranslatedField 定义的字段应该仅在 SpeedyMatchProfileActivationForm 形式的当前语言中可见)。

我想澄清一下,我想要的定义不是上面那样。所需的定义是使用表格中的当前语言,而不是始终使用英语。当当前语言不是英语时使用英语是一个错误。

你可以在这里看到代码:

tree

forms.py

models.py

现在的问题是 class SpeedyMatchProfileActivationForm(在 forms.py 中定义)。我认为这主要是因为 class 是在 get_language() returns 任何东西之前定义的。但是当 class 被定义为 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),
        }

谢谢!

我找到了解决办法。这不是最佳解决方案,但它确实有效。我将所有语言的字段添加到表单中。我们不需要的字段已在 __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 中看到更新后的 class。