我看到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
Run Code Online (Sandbox Code Playgroud)
而这段代码:forms.models.ModelChoiceField
def validate(self, value):
return Field.validate(self, value)
Run Code Online (Sandbox Code Playgroud)
Q1.为什么Django使用验证来检查所选值(来自下拉列表)是否确实在选择列表中forms.ChoiceField?
Q2.当Django使用Q1中的验证时,为了检查该值是否确实在选择列表中,为什么不检查所选值是否在模型记录中forms.models.ModelChoiceField?
验证过程从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
Run Code Online (Sandbox Code Playgroud)
首先,我们有一个to_python电话,然后是validate完成run_validators.
因此,就ModelChoiceField何时到达.validate方法而言,您的选择已经是Model实例,这就是为什么,这种验证(来自Q2)在to_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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3063 次 |
| 最近记录: |