Pau*_*per 13 serialization django-rest-framework
在Django REST框架中,创建扁平的读写串行器表示涉及什么?文档指的是"平面表示"(http://django-rest-framework.org/api-guide/serializers.html#dealing-with-nested-objects部分的末尾),但不提供示例或任何内容超出建议使用RelatedField
子类.
例如,如何提供以下关系User
和UserProfile
关系的平面表示?
# Model
class UserProfile(models.Model):
user = models.OneToOneField(User)
favourite_number = models.IntegerField()
# Serializer
class UserProfileSerializer(serializers.ModelSerializer):
email = serialisers.EmailField(source='user.email')
class Meta:
model = UserProfile
fields = ['id', 'favourite_number', 'email',]
Run Code Online (Sandbox Code Playgroud)
以上内容UserProfileSerializer
不允许写入email
字段,但我希望它足够好地表达意图.那么,如何构造一个"扁平"读写串行器来允许一个可写email
属性UserProfileSerializer
呢?在继承ModelSerializer时是否可以这样做?
谢谢.
查看Django REST框架(DRF)源代码,我认为DRF序列化程序与附带的模型紧密相关,以便进行反序列化.Field
的source
帕拉姆使这个没有那么序列化的目的.
考虑到这一点,并查看序列化程序作为封装验证和保存行为(除了它们的(非)序列化行为)我使用了两个序列化程序:每个用户和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',]
Run Code Online (Sandbox Code Playgroud)
处理序列化案例的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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7033 次 |
最近记录: |