Django ChoiceField,ModelChoiceField验证

时间:2017-04-29 13:39:28

标签: django validation

我看到forms.ChoiceField正在使用this code来验证值:

def validate(self, value):
    """
    Validates that the input is in self.choices.
    """
    super(ChoiceField, self).validate(value)
    if value and not self.valid_value(value):
        raise ValidationError(
            self.error_messages['invalid_choice'],
            code='invalid_choice',
            params={'value': value},
        )

def valid_value(self, value):
    "Check to see if the provided value is a valid choice"
    text_value = force_text(value)
    for k, v in self.choices:
        if isinstance(v, (list, tuple)):
            # This is an optgroup, so look inside the group for options
            for k2, v2 in v:
                if value == k2 or text_value == force_text(k2):
                    return True
        else:
            if value == k or text_value == force_text(k):
                return True
    return False

forms.models.ModelChoiceField this code

def validate(self, value):
    return Field.validate(self, value)

Q1。为什么Django使用验证来检查所选值(来自下拉列表)是否确实在forms.ChoiceField的选项列表中?

Q2。当Django使用Q1中的验证时,为了检查该值是否确实在选择列表中,为什么还不检查所选值是否在forms.models.ModelChoiceField的模型记录中?

2 个答案:

答案 0 :(得分:5)

验证过程从form.full_clean()开始,您按此顺序执行了form._clean_fields()form._clean_form

现在,如果您仔细查看form._clean_fields()做了什么,您可能会注意到它只调用field.clean(value, initial)并将结果收集到cleaned_data字典中。所以有趣的部分是field.clean,让我们看看那里发生了什么:

def clean(self, value):
    """
    Validate the given value and return its "cleaned" value as an
    appropriate Python object. Raise ValidationError for any errors.
    """
    value = self.to_python(value)
    self.validate(value)
    self.run_validators(value)
    return value

首先,我们进行了to_python来电,然后是validate,最后是run_validators

因此,当您到达ModelChoiceField方法时{1}},您的选择已经是一个模型实例,这就是为什么这种验证(来自Q2)发生在{{3}内部方法。

.validate

答案 1 :(得分:2)

我可以说的一件事就是表单.ChoiceField输入来自用户视角意味着用户可以使用inspect元素并输入一个不会从后端出现的选项。

但对于模型一,选择直接来自后端或数据库