如何使用Select2跳过ModelForm中Django Field的验证?

时间:2017-01-21 04:26:56

标签: django django-models django-forms select2

我在django项目的models.py中有一个表单:

class Profile(models.Model):
    choices = (("choice1", "choice1"), ("choice2", "choice2"), ("choice3", "choice3"))
    field = models.CharField(choices=choices)

在forms.py中:

class ProfileForm(ModelForm):
    class Meta:
        model = Profile
        fields = ["field"]
        widgets = {"field": Select2TagWidget}

我正在使用Select2TagWidget使我的选择字段看起来更好,但理论上,也允许用户输入不在初始列表中的选项。此前端工作完美,用户可以输入其他值。但是,当用户使用新值提交时,django表单验证会阻止保存到数据库中。所以我的问题是:

如何保留Select2标记,但是当唯一的“错误”是用户输入新值时,强制django在调用is_valid()时返回True?

我已经尝试覆盖了许多课程,但无济于事。我也看到了一些涉及使用特殊小部件的答案,但我不能使用它们,因为我需要使用Select2小部件。

编辑:

这是Field类中的Django验证代码,对我来说很麻烦(特别是for循环):

def validate(self, value, model_instance):
    """
    Validates value and throws ValidationError. Subclasses should override
    this to provide validation logic.
    """
    if not self.editable:
        # Skip validation for non-editable fields.
        return

    if self.choices and value not in self.empty_values:
        for option_key, option_value in self.choices:
            if isinstance(option_value, (list, tuple)):
                # This is an optgroup, so look inside the group for
                # options.
                for optgroup_key, optgroup_value in option_value:
                    if value == optgroup_key:
                        return
            elif value == option_key:
                return
        raise exceptions.ValidationError(
            self.error_messages['invalid_choice'],
            code='invalid_choice',
            params={'value': value},
        )

    if value is None and not self.null:
        raise exceptions.ValidationError(self.error_messages['null'], code='null')

    if not self.blank and value in self.empty_values:
        raise exceptions.ValidationError(self.error_messages['blank'], code='blank')

然而,像这样覆盖它:

class NoValidationCharField(models.CharField):
    def validate(self, value, model_instance):
        return

并使用它代替CharField并不能解决问题。

1 个答案:

答案 0 :(得分:-2)

具体来说,Django验证错误的原因是什么?

另外,尽量不要跳过Django的验证。这是有原因的。答案很可能涉及清理窗口小部件数据,但我不确定。