查看 Django REST 框架 (DRF) 源代码,我认为 DRF 序列化器与随附的模型紧密相关,以实现反序列化目的。Field
的source
参数使这不那么用于序列化目的。
考虑到这一点,并将序列化程序视为封装验证和保存行为(除了它们的(非)序列化行为),我使用了两个序列化程序:一个用于 User 和 UserProfile 模型:
class UserSerializer(serializer.ModelSerializer):
class Meta:
model = User
fields = ['email',]
class UserProfileSerializer(serializer.ModelSerializer):
email = serializers.EmailField(source='user.email')
class Meta:
model = UserProfile
fields = ['id', 'favourite_number', 'email',]
上的source
参数EmailField
充分处理序列化情况(例如,在服务 GET 请求时)。对于反序列化(例如,在处理 PUT 请求时),有必要在视图中做一些工作,结合两个序列化程序的验证和保存行为:
class UserProfileRetrieveUpdate(generics.GenericAPIView):
def get(self, request, *args, **kwargs):
# Only UserProfileSerializer is required to serialize data since
# email is populated by the 'source' param on EmailField.
serializer = UserProfileSerializer(
instance=request.user.get_profile())
return Response(serializer.data)
def put(self, request, *args, **kwargs):
# Both UserProfileSerializer and UserProfileSerializer are required
# in order to validate and save data on their associated models.
user_profile_serializer = UserProfileSerializer(
instance=request.user.get_profile(),
data=request.DATA)
user_serializer = UserSerializer(
instance=request.user,
data=request.DATA)
if user_profile_serializer.is_valid() and user_serializer.is_valid():
user_profile_serializer.save()
user_serializer.save()
return Response(
user_profile_serializer.data, status=status.HTTP_200_OK)
# Combine errors from both serializers.
errors = dict()
errors.update(user_profile_serializer.errors)
errors.update(user_serializer.errors)
return Response(errors, status=status.HTTP_400_BAD_REQUEST)