如果在django表单中设置了另一个字段,则验证字段

时间:2013-07-04 18:27:42

标签: python django django-forms

我对django表单验证感到很遗憾,尽管我阅读了文档。

我定义了以下表格:

class NewProjAccount(NewAccount):
    def __init__(self, perforce='', *args, **kwargs):
        super(NewProjAccount, self).__init__(*args, **kwargs)
        print perforce
        if 'on' in perforce:
            self.fields['perforce_depot_size'].widget.attrs[
                'required'] = True

    site = forms.ChoiceField(choices=SITE_CHOICES, required=False,
                             label="Site")
    project_name = forms.CharField(max_length=25, required=True,)
    disk_usage = forms.IntegerField(max_value=PROJ_MAX_SIZE_GB,
                                    )
    homes = forms.MultipleChoiceField(choices=SITE_CHOICES, required=False,
                                      widget=
                                      forms.widgets.CheckboxSelectMultiple(),
                                      label="Remote Homes")
    perforce_depot = forms.BooleanField(required=False)
    perforce_depot_size = forms.IntegerField(max_value=PERFORCE_MAX_SIZE_GB,
                                             required=False)

class ReviewProjAccount(NewProjAccount):
    site = forms.CharField(max_length=20, required=False,
                           label="Site")
    project_name = forms.CharField(max_length=25, required=True,)
    homes = forms.CharField(label="Remote Homes")
    perforce_depot = forms.BooleanField(required=False,
                                       widget=forms.widgets.CheckboxInput(
                                       attrs={'disabled': 'disabled'}))

两种形式都继承自:

class NewAccount(forms.Form):
    """
    Base class for all the account type
    """
    def __init__(self, readonly=False, *args, **kwargs):
        super(NewAccount, self).__init__(*args, **kwargs)

        if readonly:
            for field in self.fields.itervalues():
                field.widget.attrs['readonly'] = 'readonly'

我的想法是使用这样的形式:

 if request.method == 'POST':           
    try:
        form = NewProjAccount(perforce=request.POST['perforce_depot'],
                              data=request.POST)
    except MultiValueDictKeyError:
        print "caugh"
        if request.POST['perforce_depot_size']:
            form = ReviewProjAccount(data=initial_val,
                                 readonly=True)
        else:
            form = NewProjAccount(data=request.POST)

然而,这导致了一个非常复杂的视图函数,可能是'if'和'else'和 '尝试......例子'......

所以,我的问题是:

是否有一种简单的方法来定义表单中的字段之间的关系,以便何时 一个是True,它会触发另一个域的验证器吗? 就我而言,我想在用户选择时: perforce_depot = True'on' perforce_depot_size应将required属性设置为True

1 个答案:

答案 0 :(得分:5)

您可以查看Cleaning and validating fields that depend on each other

from django import forms

class NewProjAccount(forms.Form):
    #form attributes

    def clean(self):
        cleaned_data = super(NewProjAccount, self).clean()
        perforce_depot = cleaned_data.get("perforce_depot")
        perforce_depot_size = cleaned_data.get("perforce_depot_size")

        if perforce_depot and not perforce_depot_size:
            raise forms.ValidationError("perforce_depot_size needs to be set to true.")

        # Always return the full collection of cleaned data.
        return cleaned_data

另外,我建议你看一下django的ModelForm,它会极大地减少你的代码,并且会让它变得更简单