Django根据另一个字段表单更新表单

Django根据另一个字段表单更新表单,django,forms,field,Django,Forms,Field,我有以下Django表格: label = forms.CharField(label="Label", min_length=2, max_length=100, required=True, widget=forms.TextInput(attrs={'class': 'form-control inp

我有以下Django表格:

label = forms.CharField(label="Label",
                        min_length=2,
                        max_length=100,
                        required=True,
                        widget=forms.TextInput(attrs={'class': 'form-control input-sm'}))

hour = forms.ChoiceField(label="Hour",
                         choices=choice_hour,
                         required=True,
                         widget=forms.Select(attrs={'class': 'form-control input-sm'}))

minute = forms.ChoiceField(label="Minute",
                           choices=choice_minute,
                           required=True,
                           widget=forms.Select(attrs={'class': 'form-control input-sm'}))

period = forms.MultipleChoiceField(label="Day of week",
                                   choices=choice_period,
                                   required=True,
                                   error_messages={'required': 'At least you must select one day'},
                                widget=forms.CheckboxSelectMultiple(renderer=HorizontalCheckboxRenderer))


snooze = forms.ChoiceField(label="Auto stop",
                           choices=choice_snooze,
                           required=True,
                           widget=forms.Select(attrs={'class': 'form-control input-sm'}))


mode = forms.ChoiceField(label="Mode",
                          choices=choice_mode,
                          required=True,
                          widget=forms.Select(attrs={'class': 'form-control input-sm'}))

if mode == 'music':
        webradio = forms.ModelChoiceField(queryset=Webradio.objects.all(),
                                      widget=forms.Select(attrs={'class': 'form-control input-sm'}), required=False)
    else:
        webradio = forms.ModelChoiceField(queryset=Webradio.objects.all(),
                                  widget=forms.Select(attrs={'class': 'form-control input-sm'}), required=True)

    class Meta:
        model = Alarmclock
        fields = ['label', 'hour', 'minute', 'period', 'snooze', 'mode', 'webradio']
“模式”字段表单允许知道用户想要的是“收音机”还是“音乐”

当模式为“音乐”时,webradio字段可以为空。 但当模式为“radio”时,必须设置webradio字段

如何根据模式更新webradio字段表单

我尝试使用IF条件,但我认为找不到模式变量,webradio字段始终是必需的


谢谢

我想这应该能奏效

class FormName(forms.ModelForm):

    label = forms.CharField(label="Label",
                            min_length=2,
                            max_length=100,
                            required=True,
                            widget=forms.TextInput(attrs={'class': 'form-control input-sm'}))

    hour = forms.ChoiceField(label="Hour",
                             choices=choice_hour,
                             required=True,
                             widget=forms.Select(attrs={'class': 'form-control input-sm'}))

    minute = forms.ChoiceField(label="Minute",
                               choices=choice_minute,
                               required=True,
                               widget=forms.Select(attrs={'class': 'form-control input-sm'}))

    period = forms.MultipleChoiceField(label="Day of week",
                                       choices=choice_period,
                                       required=True,
                                       error_messages={'required': 'At least you must select one day'},
                                    widget=forms.CheckboxSelectMultiple(renderer=HorizontalCheckboxRenderer))


    snooze = forms.ChoiceField(label="Auto stop",
                               choices=choice_snooze,
                               required=True,
                               widget=forms.Select(attrs={'class': 'form-control input-sm'}))


    mode = forms.ChoiceField(label="Mode",
                              choices=choice_mode,
                              required=True,
                              widget=forms.Select(attrs={'class': 'form-control input-sm'}))

    webradio = forms.ModelChoiceField(queryset=Webradio.objects.all(),
                                      widget=forms.Select(attrs={'class': 'form-control input-sm'}), required=True)

    class Meta:
        model = Alarmclock
        fields = ['label', 'hour', 'minute', 'period', 'snooze', 'mode', 'webradio']

    def clean_mode(self):
        mode = self.cleaned_data.get('mode')
        if mode == 'music':
            self.fields['webradio'].required = False
        return super(FormName,self).clean_mode()

它基本上是根据mode的值,在运行中更改webradio字段的required属性。

将webradio字段定义为notrequired,然后在clean方法中进行验证(clean的目的是对相互依赖的字段进行验证)

查看更多详细信息

请注意,Django 1.7中更改了此方法:

在Django的早期版本中,需要form.clean()来返回已清理数据的字典。此方法仍然可以返回要使用的数据字典,但不再需要它


您必须重写
\uuuu init\uuu
方法才能执行此操作。这是您的完整表单类吗?不,我有一些变量/列表/元组,它们在类的顶部进行初始化(选项\模式等),谢谢,但它不起作用。”超级对象没有“清除模式”属性。如果我删除这一行(返回),django将启动,但是表单返回mode和webradios小部件的错误。mode小部件没有显示任何错误,这是我的错误。但是webradio小部件在每种情况下都会出错。。我想我理解“super”关键字:它调用类本身,不是吗?保留所有字段的值不是问题吗?super调用父类的方法。到底是什么错误?您必须将分配给表单类的名称替换为“FormName”。很抱歉,我解释得不好,确切的错误是,即使我选择了音乐,Webradio小部件也会在网页上显示“必填字段”。所以,webradio字段表单不要更改为False。好的,在阅读了文档之后,我明白了原因。使用您的代码,发送表单时,页面将返回
超级对象没有属性clean_mode
。因此,我将
clean_mode
重命名为
cleanmode
,我认为现在它没有检测到函数。。是的,我的名字是正确的。谢谢,也许更好。但是我还有一个错误,我想这是因为我的视图在清理完表单中的数据后启动了“form.is\u valid()”。在我的views.py中,我在表单上有一个form.is\u valid()。我在文档中读到,“is_valid()”将传递许多“clean_***”方法,我想问的是,在另一个之前启动clean_数据是否没有问题。。抱歉,可能不是很清楚这不是问题,数据已经验证过了。clean_*方法的工作方式类似于额外的验证。如果您想了解更多有关验证过程的信息,请接受。如果答案确实解决了您的问题,请接受。对不起,我不知道为什么,现在它可以工作了,谢谢!只是我使用了“forms.ModelForm”,它使用了一个自动的ValidationError消息,所以定制消息不起作用。但我会读更多关于这方面的内容。
class Form(forms.ModelForm):

    # other fields ...

    mode = forms.ChoiceField(
        label="Mode", choices=choice_mode, required=True,
        widget=forms.Select(attrs={'class': 'form-control input-sm'})
    )
    webradio = forms.ModelChoiceField(
        queryset=Webradio.objects.all(),
        widget=forms.Select(attrs={'class': 'form-control input-sm'}),
        required=False
    )

    class Meta:
        model = Alarmclock
        fields = ['label', 'hour', 'minute', 'period', 'snooze', 'mode', 'webradio']

    def clean(self):
        mode = self.cleaned_data.get('mode')
        if mode == 'music':
            webradio = self.cleaned_data.get('webradio')
            if not webradio:
                raise forms.ValidationError({'webradio': 'Webradio field is required.'})