即使在清除方法覆盖之后,表单字段仍然会错误地验证

Form field still validates falsely even after clean method override

我有一个限制小数位数的模型:

lat = models.DecimalField(max_digits=8, decimal_places=5, null=True, blank=True)

我从中创建了一个 ModalForm 但是,如果他们提交的内容超过 5 位,我想限制小数位数。所以我做了一个自定义的清理方法:

def clean_lat(self):
    lat = self.cleaned_data['lat']
    return round(lat, 4)

但它仍然引发了一个 ValidationError 我允许的小数位数更多的问题。我做错了什么?

form.is_valid方法做了一件非常简单的事情:

def full_clean(self):
    """
    Cleans all of self.data and populates self._errors and
    self.cleaned_data.
    """
    self._errors = ErrorDict()
    if not self.is_bound:  # Stop further processing.
        return
    self.cleaned_data = {}
    # If the form is permitted to be empty, and none of the form data has
    # changed from the initial data, short circuit any validation.
    if self.empty_permitted and not self.has_changed():
        return

    self._clean_fields()
    self._clean_form()
    self._post_clean()

建议你进入源码(django/forms/forms.py),很快就会定位到原因。

有两个选项可以解决这个问题。

第一个是像这样重写你的模型init方法

def __init__(self, *args, **kwargs):
    super(TestForm, self).__init__(*args, **kwargs)
    self.fields['lat'].decimal_places = None
    self.fields['lat'].max_digits = None

这将禁用模型形式的小数位和最大数字验证。然后你的 clean_lat 方法应该确保确保表单数据验证。模型仍将截断/舍入/验证十进制值。

第二个选项是从模型中删除 max_digits=8, decimal_places=5 并确保在表单 clean_lat 方法中进行验证。如果在不使用 ModelForm.

的情况下保存对象,这可能会产生问题