繁体   English   中英

Django表单 - 如何覆盖字段验证

[英]Django forms - how to override field validation

在表单中,我有某些字段,这些字段未经过正确验证。 我希望覆盖django验证并改为使用自己的验证。 当我覆盖clean()方法时,字段self.errors已经填充了错误验证字段的错误。 我应该覆盖哪种方法,这些错误产生在哪里?

通过重写clean()和类似的方法,只能实现对django默认验证的扩展。 我想阻止此默认验证发生。

编辑:尝试过验证器
这是我尝试过的:

253   def validate_gallery(value):
254     print 'validate galley'
255     return True
256   
257   def validate_cover_photo(value):
258     print 'validate_cf'
259     return True
260 
261   cover_photo_widget = SelectWithDefaultOptions(attrs={
262       'class': 'chosen-select-no-single',
263       'id': 'select-cover-photo',
264       'data-placeholder': 'Select Cover Photo',
265       'style': 'width: 200px;',
266       'tabindex': '-1',
267     });
268 
269   gallery_widget = SelectWithDefaultOptions(attrs={
270       'class': 'chosen-select-no-single',
271       'id': 'select-galley',
272       'data-placeholder': 'Select Gallery',
273       'style': 'width: 200px;',
274       'gallery-select': '',
275       'tabindex': '-1',
276       'organisator-profile-specific': '',
277     });
278   
279   gallery = forms.ChoiceField(widget = gallery_widget, validators = [validate_gallery])
280   cover_photo = forms.ChoiceField(widget = cover_photo_widget, validators = [validate_cover_photo])

甚至没有调用那些验证器。 似乎错误搜索过程在validate()函数调用结束,这在调用任何验证器之前发生。

编辑:发布全班

240 def validate_gallery(value):
241   print 'validate galley'
242   return True
243 
244 def validate_cover_photo(value):
245   print 'validate_cf'
246   return True
247 
248 class EventDetailForm(NgFormValidationMixin, NgModelForm):
249   def __init__(self, *args, **kwargs):
250     super(EventDetailForm, self).__init__(*args, **kwargs)
251     self.fields['end_date'].required = False
252     self.fields['description'].required = False
253     self.fields['start_date'].input_formats = DATE_TIME_INPUT_FORMATS
254     self.fields['end_date'].input_formats = DATE_TIME_INPUT_FORMATS
255 
256     arguments_length = len(args)
257     if arguments_length > 0:
258       post_data = args[0]
259       self.old_title = post_data.get('old_title', None)
260 
261   cover_photo_widget = SelectWithDefaultOptions(attrs={
262       'class': 'chosen-select-no-single',
263       'id': 'select-cover-photo',
264       'data-placeholder': 'Select Cover Photo',
265       'style': 'width: 200px;',
266       'tabindex': '-1',
267     });
268 
269   gallery_widget = SelectWithDefaultOptions(attrs={
270       'class': 'chosen-select-no-single',
271       'id': 'select-galley',
272       'data-placeholder': 'Select Gallery',
273       'style': 'width: 200px;',
274       'gallery-select': '',
275       'tabindex': '-1',
276       'organisator-profile-specific': '',
277     });
278 
279   gallery = forms.ChoiceField(widget = gallery_widget, validators = [validate_gallery])
280   cover_photo = forms.ChoiceField(widget = cover_photo_widget, validators = [validate_cover_photo])
281 
282   class Meta:
283     model = Event
284     fields = ('title', 'description', 'end_date', 'start_date')
285     widgets = {
286       'title': forms.TextInput(attrs={
287         'editable-detail': '',
288       }),
289       'description': forms.TextInput(attrs={
290         'class': 'panel-body',
291         'id': 'event-description-editable',
292         'editable-detail': '',
293       }),
294       'start_date': DateTimeWidget(attrs = {
295         'class': 'datetimepicker col-xs-6',
296         'id': 'event-start-date-editable',
297         'editable-detail': '',
298       }),
299       'end_date': DateTimeWidget(attrs = {
300         'class': 'datetimepicker col-xs-6',
301         'id': 'event-end-date-editable',
302         'editable-detail': '',
303       }),
304     }
305 
306   def clean(self):
307     cleaned_data = self.cleaned_data
308 
309     print self.errors
310 
311     return cleaned_data
312     
313   def save(self, commit=True):
314     old_title = self.old_title
315     event = Event()
316 
317     cover_photo_title = self.cleaned_data['cover_photo']
318     cover_photo = Photo.objects.filter(title=cover_photo_title)
319     
320     gallery_title = self.cleaned_data['gallery']
321     gallery = Gallery.objects.filter(title=gallery_title)
322 
323     event.title = self.cleaned_data['title']
324     event.description = self.cleaned_data['desription']
325     event.start_date = self.cleaned_date['start_date']
326     event.end_date = self.cleaned_data['end_date']
327     event.cover_photo = cover_photo
328     event.gallery = gallery
329 
330     if commit:
331       event.save()
332       
333     return event
334 

clean()我可以看到错误存在, save()从不执行。

为什么不编写自己的Field类,它有自己的validate方法,因为它在验证器本身之前被调用:

class MyCustomChoiceField(ChoiceField):

    def validate(self, value):
        <do something to validate your field>

然后使用它:

gallery = MyCustomChoiceField(widget = gallery_widget)

除非字段的验证依赖于另一个字段的值,否则最好是在表单字段定义中设置验证器函数。

Django文档中的示例:

from django import forms

class MyForm(forms.Form):
    even_field = forms.IntegerField(validators=[validate_even])

如果验证不是特定于表单,您甚至可以在模型中设置验证器。

您可以覆盖调用以清理数据的def clean_YOUR_VARIABLE_NAME方法

参考: 清理特定的字段属性

例如:

class EmailForm(forms.Form):
    your_email = forms.EmailField(label='Your E-mail address', required=True)

    def clean_your_email(self):
        data = self.cleaned_data['your_email']
        # Check some condition over data
        # raise ValidationError for bad results
        # else return data

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM