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

vic*_*175 3 python django validation django-forms

在表单中,我有某些字段,这些字段未经过正确验证.我希望覆盖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])
Run Code Online (Sandbox Code Playgroud)

甚至没有调用那些验证器.似乎错误搜索过程在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 
Run Code Online (Sandbox Code Playgroud)

clean()我可以看到错误在那里,save()是从来没有执行.

pro*_*nte 9

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

class MyCustomChoiceField(ChoiceField):

    def validate(self, value):
        <do something to validate your field>
Run Code Online (Sandbox Code Playgroud)

然后使用它:

gallery = MyCustomChoiceField(widget = gallery_widget)
Run Code Online (Sandbox Code Playgroud)

  • 对于ModelChoice,您需要覆盖`to_python`方法. (2认同)

mim*_*imo 5

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

Django文档中的示例:

from django import forms

class MyForm(forms.Form):
    even_field = forms.IntegerField(validators=[validate_even])
Run Code Online (Sandbox Code Playgroud)

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

  • 我尝试过,我仍然无法达到我想要的。检查我的编辑。 (2认同)

Hit*_*ani 5

您可以覆盖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
Run Code Online (Sandbox Code Playgroud)

  • 这些干净的技术提供了向默认验证添加额外验证的机会。我想避免使用默认值。 (3认同)