使用Django中的自定义多值小部件验证多值字段

使用Django中的自定义多值小部件验证多值字段,django,django-forms,django-multiwidget,Django,Django Forms,Django Multiwidget,我想有一个字段和一个小部件,让它有一个“近似”的日期,想法是有一个且只有一个以下内容: 确切日期 一年也许一个月 第一年和第二年 一些压缩的有效值可能是: “1988/08/07,,,,” “,1988,,” “,1988,08,” “,,19971999” 问题是,我无法验证字段是否只有上述三个选项中的一个,在字段定义中,我尝试创建了validate和clean方法,但没有得到验证,我怀疑字段和小部件之间的链接不正确。我错过了什么 为此,我创建了一个小部件: 类近似DateWidget

我想有一个字段和一个小部件,让它有一个“近似”的日期,想法是有一个且只有一个以下内容:

  • 确切日期
  • 一年也许一个月
  • 第一年和第二年
一些压缩的有效值可能是:

  • “1988/08/07,,,,”
  • “,1988,,”
  • “,1988,08,”
  • “,,19971999”
问题是,我无法验证字段是否只有上述三个选项中的一个,在字段定义中,我尝试创建了validate和clean方法,但没有得到验证,我怀疑字段和小部件之间的链接不正确。我错过了什么

为此,我创建了一个小部件:

类近似DateWidget(forms.MultiWidget):
def(self,attrs=None,choices=()):
self.widgets=(
forms.DateInput(attrs=attrs),
forms.TextInput(attrs=attrs),
forms.Select(attrs=attrs,choices=choices),
forms.TextInput(attrs=attrs),
forms.TextInput(attrs=attrs),
)
super(ApproximatedDateWidget,self)。\uuuu init(self.widgets,attrs=attrs)
def解压缩(自身,值):
尝试:
打印值
如果值:
l=值。拆分(“,”)
打印l
如果l[0]和l[0]="":                    
d=l[0]。拆分(“/”)
打印d
返回[日期(int(d[0])、int(d[1])、int(d[2])、无、无、无]
其他:
返回[无,l[1],l[2],l[3],l[4]]
返回[无,无,无,无,无]
除:
提升
返回[无,无,无,无,无]
def格式_输出(自、渲染_小部件):
返回标记为“安全(u)”
确切日期:{0}
年份和月份:{1}{2}
年月
在:{3}和{4}之间
一年
“.format(*呈现的_小部件))
以及表单字段:

从工具导入月份选择
从验证器导入nullableinteger
类近似数据字段(forms.MultiValueField):
"""
字段,该字段允许有一个近似日期,其中一个
确切日期、月份和年份或年份范围
"""
def u u init u;(self,required=False,widget=None,label=None,initial=None,
help_text=None,attrs={},*args,**kwargs):
self.widget=ApproximatedDateWidget(attrs=attrs,choices=MonthChoices)
widgets=self.widget.widgets
字段=(
forms.DateField(required=required,validators=[lessthantomorrow],widget=widgets[0]),
CharField(widget=widgets[1],required=required,max_length=4,validators=[nullableinteger]),
forms.ChoiceField(required=required,choices=MonthChoices,widget=widgets[2]),
CharField(widget=widgets[3],required=required,max_length=4,validators=[nullableinteger]),
CharField(widget=widgets[4],required=required,max_length=4,validators=[nullableinteger]),
)
super(ApproximatedDateField,self)。\uuuuu init\uuuuu(fields=fields,required=required,widget=widget,
标签=标签,首字母=首字母,帮助文本=帮助文本)
def压缩(自我,数据列表):
返回“{0}、{1}、{2}、{3}、{4}”格式(数据列表[0].strftime(“%d/%m/%Y”)、数据列表[1]、(数据列表[2]和数据列表[2].id)或“”、数据列表[3]、数据列表[4])
def验证(自身、值):
super(近似数据域,self).验证(值)
如果值[0]不是无且(值[1]不是无或值[2]不是无)和(值[1]不是无或值[2]不是无):
raise ValidationError(u'请仅填写准确日期或年、月或范围年')
def清洁(自身,数值):
super(近似数据域,self).clean(值)
如果值[0]不是无且(值[1]不是无或值[2]不是无)和(值[1]不是无或值[2]不是无):
raise ValidationError(u'请仅填写准确日期或年、月或范围年')

我编写了一个自定义小部件和多值字段来处理英尺和英寸:,还有一个是数学验证码:


我将我的验证放在多值字段的压缩方法中,这对这些字段非常有效。您可以查看该代码段和repo,看看这是否让您走上了正确的轨道。

我编写了一个自定义小部件和多值字段来处理英尺和英寸:,还有另一个是数学验证码:


我将我的验证放在多值字段的压缩方法中,这对这些字段非常有效。您可以查看该代码段和repo,看看这是否让您走上了正确的轨道。

这是一些原始代码:`from django.core.exceptions import ValidationError#稍后,在小部件中:def compress(self,**kwargs)if validation_error_条件:raise ValidationError(u'Please change XYZ'))`这是一些原始代码:`from django.core.exceptions import ValidationError#稍后,在小部件中:def compress(self,**kwargs)if validation_error_条件:raise ValidationError(u'Please change XYZ'))`