python Django 表单验证:使“必需”成为条件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2306800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:19:35  来源:igfitidea点击:

Django form validation: making "required" conditional?

pythondjangodjango-forms

提问by ChrisW

I'm new to Django (and Python), and am trying to figure out how to conditionalize certain aspects of form validation. In this case, there's a HTML interface to the application where the user can choose a date and a time from widgets. The cleanmethod on the form object takes the values of the time and date fields and turns them back into a datetime.

我是 Django(和 Python)的新手,我正在尝试弄清楚如何对表单验证的某些方面进行条件化。在这种情况下,应用程序有一个 HTML 界面,用户可以在其中从小部件中选择日期和时间。的clean形式对象方法需要的时间和日期字段的值,并把它们放回一个datetime

In addition to the HTML interface, there's also an iPhone client making calls into the application, and I'd like to pass a UNIX timestamp-style time value in.

除了 HTML 界面,还有一个 iPhone 客户端调用应用程序,我想传入一个 UNIX 时间戳样式的时间值。

My form code looks like this:

我的表单代码如下所示:

class FooForm(forms.ModelForm):
    foo_date             = forms.CharField(required=True, widget=forms.RadioSelect(choices=DATE_CHOICES))
    foo_time             = forms.CharField(required=True, widget=SelectTimeWidget())
    foo_timestamp        = forms.CharField(required=False)

How do I make foo_dateand foo_timerequired unlessfoo_timestampis provided?

除非提供foo_date否则我如何制作和foo_time要求?foo_timestamp

回答by Benjamin Wohlwend

This is done with the cleanmethod on the form. You need to set foo_dateand foo_timeto required=False, though, because cleanis only called after every field has been validated (see also the documentation).

这是通过clean表单上的方法完成的。你需要设置foo_datefoo_timerequired=False,不过,因为clean每个领域已被证实后,才会调用(另见文档)。

class FooForm(forms.Form)
    # your field definitions

    def clean(self):
        data = self.cleaned_data
        if data.get('foo_timestamp', None) or (data.get('foo_date', None) and data.get('foo_time', None)):
            return data
        else:
            raise forms.ValidationError('Provide either a date and time or a timestamp')

回答by Elliott

I found myself needing a "standard" way to do this, as my forms have several conditionally required fields. So I created a superclass with the following method:

我发现自己需要一种“标准”的方式来做到这一点,因为我的表单有几个有条件的必填字段。所以我用以下方法创建了一个超类:

def validate_required_field(self, cleaned_data, field_name, message="This field is required"):
    if(field_name in cleaned_data and cleaned_data[field_name] is None):
        self._errors[field_name] = self.error_class([message])
        del cleaned_data[field_name]

And then in my form's clean method I have:

然后在我的表单的干净方法中,我有:

def clean(self):
    cleaned_data = super(FormClass, self).clean()
    if(condition):
        self.validate_required_field(cleaned_data, 'field_name')

It's worked perfectly for me so far.

到目前为止,它对我来说非常有效。