Django Serializer:如何验证模型实例?
Django Serializer: How can I validate a model instance?
我对 Django 序列化程序还很陌生,仍然对它们的工作方式感到困惑。
我有一个相当一般的场景,其中我正在调用我的 api,它只是在我的模型对象中设置一个字段并保存它(假设记录已经存在并且正在更新)。但是,我需要在保存之前验证这个模型对象。
api.py
@detail_route(methods=['POST'], url_path='submit-draft')
def submit_draft(self, request, *args, **kwargs):
booking = self.get_object()
# serializer with custom validations.
serializer = self.get_serializer(booking)
serializer.is_valid(raise_exception=True)
booking.submit_draft(by=request.user)
booking.save()
data = serializers.BookingDetailSerializer(booking, context={'request': request}).data
return response.Ok(data)
serializers.py
class BookingCreateUpdateSerializer(serializers.ModelSerializer):
date = serializers.CharField()
duration = serializers.IntegerField(required=True, )
created_by = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault(), )
modified_by = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault(), )
....
class Meta:
model = models.Booking
fields = [
'title',
'date',
'duration',
'client',
'created_by',
'modified_by',
....
]
但是,我得到这个错误:
AssertionError: Cannot call '.is_valid()' as no 'data=' keyword argument was passed when instantiating the serializer instance.
我知道序列化程序需要一个字典而不是实际的模态对象。但我无法弄清楚如何实现我想要的。验证模型对象。任何人都可以建议正确的方法吗?
您可以使用序列化器来:
1) 将您的对象序列化为字典。在这种情况下,您不需要调用 is_valid,因为该对象已经创建并且具有有效值。所以你可以这样做:
serializer = BookingCreateUpdateSerializer(booking)
return Response(serializer.data)
2) 使用序列化程序序列化输入并创建新对象。在这种情况下,输入是一个字典,需要在调用保存之前先对其进行验证。你可以这样做:
serializer = BookingCreateUpdateSerializer(data=input_dict)
serializer.is_valid()
serializer.save()
更新回复评论
您可以执行以下操作以使用序列化程序更新实例:
serializer = BookingCreateUpdateSerializer(booking, data=input_data_to_update, partial=True)
serializer.is_valid()
instance = serializer.save()
# and serialize the updated instance for response using another serializer
output_data = BookingDetailSerializer(instance).data
这就是我绞尽脑汁将近一天后终于奏效的方法。
api.py
@detail_route(methods=['POST'], url_path='submit-draft')
def submit_draft(self, request, *args, **kwargs):
# Step1. Get current model instance.
booking = self.get_object()
# Step2. Serialize the model instance using same serializer as in Step5.
booking_data = serializers.BookingDetailSerializer(booking, context={'request':
request}).data
# Step3. Deserialize the data from Step2 (using `BookingCreateUpdateSerializer` serializer
as mentioned in description and check for validations.
serializer = self.get_serializer(data=booking_data)
serializer.is_valid(raise_exception=True)
# Step4. If no validation error, set the required field and save the instance.
booking.submit_draft(by=request.user)
booking.save()
# Step5. Return response.
data = serializers.BookingDetailSerializer(booking, context={'request': request}).data
return response.Ok(data)
我今天学到了更多关于序列化程序的知识。我们可以将模型实例传递到不同的序列化器中,并根据我们的要求改变它的形状。
我对 Django 序列化程序还很陌生,仍然对它们的工作方式感到困惑。
我有一个相当一般的场景,其中我正在调用我的 api,它只是在我的模型对象中设置一个字段并保存它(假设记录已经存在并且正在更新)。但是,我需要在保存之前验证这个模型对象。
api.py
@detail_route(methods=['POST'], url_path='submit-draft')
def submit_draft(self, request, *args, **kwargs):
booking = self.get_object()
# serializer with custom validations.
serializer = self.get_serializer(booking)
serializer.is_valid(raise_exception=True)
booking.submit_draft(by=request.user)
booking.save()
data = serializers.BookingDetailSerializer(booking, context={'request': request}).data
return response.Ok(data)
serializers.py
class BookingCreateUpdateSerializer(serializers.ModelSerializer):
date = serializers.CharField()
duration = serializers.IntegerField(required=True, )
created_by = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault(), )
modified_by = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault(), )
....
class Meta:
model = models.Booking
fields = [
'title',
'date',
'duration',
'client',
'created_by',
'modified_by',
....
]
但是,我得到这个错误:
AssertionError: Cannot call '.is_valid()' as no 'data=' keyword argument was passed when instantiating the serializer instance.
我知道序列化程序需要一个字典而不是实际的模态对象。但我无法弄清楚如何实现我想要的。验证模型对象。任何人都可以建议正确的方法吗?
您可以使用序列化器来:
1) 将您的对象序列化为字典。在这种情况下,您不需要调用 is_valid,因为该对象已经创建并且具有有效值。所以你可以这样做:
serializer = BookingCreateUpdateSerializer(booking)
return Response(serializer.data)
2) 使用序列化程序序列化输入并创建新对象。在这种情况下,输入是一个字典,需要在调用保存之前先对其进行验证。你可以这样做:
serializer = BookingCreateUpdateSerializer(data=input_dict)
serializer.is_valid()
serializer.save()
更新回复评论
您可以执行以下操作以使用序列化程序更新实例:
serializer = BookingCreateUpdateSerializer(booking, data=input_data_to_update, partial=True)
serializer.is_valid()
instance = serializer.save()
# and serialize the updated instance for response using another serializer
output_data = BookingDetailSerializer(instance).data
这就是我绞尽脑汁将近一天后终于奏效的方法。
api.py
@detail_route(methods=['POST'], url_path='submit-draft')
def submit_draft(self, request, *args, **kwargs):
# Step1. Get current model instance.
booking = self.get_object()
# Step2. Serialize the model instance using same serializer as in Step5.
booking_data = serializers.BookingDetailSerializer(booking, context={'request':
request}).data
# Step3. Deserialize the data from Step2 (using `BookingCreateUpdateSerializer` serializer
as mentioned in description and check for validations.
serializer = self.get_serializer(data=booking_data)
serializer.is_valid(raise_exception=True)
# Step4. If no validation error, set the required field and save the instance.
booking.submit_draft(by=request.user)
booking.save()
# Step5. Return response.
data = serializers.BookingDetailSerializer(booking, context={'request': request}).data
return response.Ok(data)
我今天学到了更多关于序列化程序的知识。我们可以将模型实例传递到不同的序列化器中,并根据我们的要求改变它的形状。