[英]django rest framework serializers and django forms
Question : How to write DRY code for field validation in both form and serializer? 问题 :如何在表单和序列化器中编写用于字段验证的DRY代码?
Example : I have simple django app with model form, which validates passengers
field for Order
: 示例 :我有简单的django应用程序和模型表单,它验证Order
passengers
字段:
def clean_passengers(self):
passengers = self.cleaned_data['passengers']
if passengers > self.flight.available_seats:
raise forms.ValidationError(
_(u'''Passengers count can`t be greater then seats count'''))
return passengers
And same code for validation in Order
serializer: 和Order
serializer中的验证代码相同:
def validate_passengers(self, attrs, source):
passengers = attrs[source]
if passengers > self.flight.available_seats:
raise serializers.ValidationError(
_(u'''Passengers count can`t be greater then seats count'''))
return attrs
This isn`t DRY and I have write same logic twice. 这不是干的,我写了两次相同的逻辑。 How I can avoid this? 我怎么能避免这个? Maybe I can inherit serializer from form or something like this. 也许我可以从表单或类似的东西继承序列化程序。
You can use your serializer to deserialize and validate the data inside the is_valid
method of your form. 您可以使用序列化程序反序列化并验证表单的is_valid
方法中的数据。
class MyModelForm(ModelForm):
def is_valid(self):
# Call super's is_valid to populate cleaned_data and do basic field validation
valid = super(MyModelForm, self).is_valid()
if not valid:
return False
serializer = MyModelSerializer(data=self.cleaned_data)
return serializer.is_valid()
Here my implementation of reusable validation class for model forms. 这里我为模型表单实现了可重用的验证类。 All native Django things are here except rewritten get_serializer
method. 除了重写的get_serializer
方法之外,所有原生的Django都在这里。 Verified working state with Django 1.8.13. 使用Django 1.8.13验证工作状态。
class RestFrameworkValidationModelForm(forms.ModelForm):
serializer_class = None
def get_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer()` method."
% self.__class__.__name__
)
return self.serializer_class(*args, **kwargs)
def is_valid(self):
if super(RestFrameworkValidationModelForm, self).is_valid():
serializer = self.get_serializer(data=self.cleaned_data)
valid = serializer.is_valid()
self.add_error(None, serializer.errors)
return valid
return False
And here is example of usage: 以下是用法示例:
class ExperimentForm(RestFrameworkValidationModelForm):
serializer_class = ExperimentSerializer
class Meta:
model = Experiment
exclude = []
I would suggest putting all validation (when possible) into the model (validators or clean
). 我建议将所有验证(如果可能)放入模型(验证器或clean
)。
ModelForm
and ModelSerializer
then use the mode-validation. 然后ModelForm
和ModelSerializer
使用模式验证。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.