我看到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
的模型记录中?
答案 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元素并输入一个不会从后端出现的选项。
但对于模型一,选择直接来自后端或数据库