我看到forms.ChoiceField正在使用这段代码验证值:
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 这段代码
def validate(self, value):
return Field.validate(self, value)Q1。为什么Django使用验证来检查所选的值(从下拉列表中)是否确实在forms.ChoiceField的选择列表中
Q2。当Django使用来自Q1的验证来检查该值是否确实在选择列表中时,为什么不也检查所选值是否在forms.models.ModelChoiceField的模型记录中
发布于 2017-05-03 21:34:52
验证过程从清洁()开始,您可以按照这样的顺序执行字段()和表格。
现在,如果您仔细看看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而言,当您到达.validate方法时,您的选择已经是一个模型实例,这就是为什么,这种验证(来自Q2)正在python方法中进行。
def to_python(self, value):
if value in self.empty_values:
return None
try:
key = self.to_field_name or 'pk'
value = self.queryset.get(**{key: value})
except (ValueError, TypeError, self.queryset.model.DoesNotExist):
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
return value发布于 2017-05-03 09:15:30
我可以说,对于forms.ChoiceField,输入是从用户的角度来的,这意味着用户可以使用检查元素并输入一个没有出现在后端的选择。
但是对于模型一,选择直接来自后端或数据库。
https://stackoverflow.com/questions/43696337
复制相似问题