首页 > 解决方案 > Django,为 ModelChoiceField 编写干净方法的指南

问题描述

我已阅读文档,但只能找到有关如何为表单中的字段编写干净方法的指南:https ://docs.djangoproject.com/en/3.1/ref/forms/validation/#cleaning-a-特定字段属性

但是我创建了一个继承自ModelChoiceField. 我希望添加一些自定义验证和清理,附加到字段而不是表单,因为该字段用于多种表单,因此保持干燥。

我可以尝试创建一个干净的方法,但实际上传递了什么参数,应该返回什么似乎在文档中缺少,或者我找不到它。

这是我希望添加自定义清理和验证的字段:

class FooChoiceField(forms.ModelChoiceField):
    def __init__(self, required=True):
        queryset = Foo.objects.filter(enabled=True).order_by('name')
        super().__init__(
            widget=forms.RadioSelect,
            queryset=queryset,
            to_field_name='id',  # The radio button value field
            required=required,
            empty_label=None,
        )
        self.error_messages = {
            'required': "Please select a Foo.",
            'invalid_choice': "Invalid Foo selected, please try again.",
        }

    # Pass the whole DB object into the template so one can access all fields
    def label_from_instance(self, obj):
        return obj

这是一个猜测,虽然它被调用,但清理后的字段总是以 结尾None,即使它有效:

class FooChoiceField(forms.ModelChoiceField):
    ...

    def clean(self, value):
        if value != 'correct':
            raise ValidationError("Value is challenged in it's correctness")
        return value

    def validate(self, obj):
        if obj.foo != 'foo':
            raise ValidationError("Validation Error on foo")

标签: djangodjango-formsdjango-validation

解决方案


如果这是一个模型字段,并且验证被重复使用,您应该将验证移到模型本身上

def validate_correct(value):
    if value != 'correct':
        raise ValidationError("!",  code='incorrect')


class MyModel(models.Model):
    my_field = models.CharField(
        max_length=31,
        validators=[validate_correct],
    )

如果你想保留你的新表单域,你也应该添加一些验证器

class MyModelChoiceFields(forms.ModelChoiceField):
    default_validators = [validate_correct]
    default_error_messages = {'incorrect': "This is not correct"}

推荐阅读