Django REST框架平板,读写串行器

时间:2013-08-19 16:46:38

标签: serialization django-rest-framework

在Django REST框架中,创建扁平的读写串行器表示涉及什么?文档引用了“平面表示”(http://django-rest-framework.org/api-guide/serializers.html#dealing-with-nested-objects部分的末尾),但除了建议使用RelatedField子类之外,不提供示例或任何内容。

例如,如何在下方提供UserUserProfile关系的平面表示?

# 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',]

以上UserProfileSerializer不允许写入email字段,但我希望它能充分表达意图。那么,如何构造一个“扁平”读写串行器来允许email上的可写UserProfileSerializer属性?是否可以在继承ModelSerializer时执行此操作?

感谢。

3 个答案:

答案 0 :(得分:6)

在查看Django REST框架(DRF)源代码时,我认为DRF序列化程序与附带的模型紧密相关,以便进行反序列化。 Field的{​​{1}} param使序列化目的更少。

考虑到这一点,并查看序列化程序作为封装验证和保存行为(除了它们的(非)序列化行为)我使用了两个序列化程序:每个用户和UserProfile模型一个:

source

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参数足以处理序列化情况(例如,在为GET请求提供服务时)。对于反序列化(例如,当处理PUT请求时),有必要在视图中做一些工作,结合两个序列化器的验证和保存行为:

EmailField

答案 1 :(得分:2)

首先:更好地处理嵌套写入。

第二:Serializer Relations docsPrimaryKeyRelatedFieldSlugRelatedField说“默认情况下此字段为读写...” - 所以如果您的电子邮件字段是唯一的(是?)它可能是你可以使用SlugRelatedField它只会工作 - 我还没有尝试过(但是)。

第三:相反,我使用了一个普通的Field子类,它使用source="*" technique来接受整个对象。从那里我手动拉取to_native中的相关字段并返回 - 这是只读的。为了写我在post_save检查了request.DATA并在那里更新了相关对象 - 这不是自动的,但它可以工作。

所以,第四:看看你已经得到了什么,我的方法(上面)相当于将你的email字段标记为只读,然后实施post_save来检查{{1} }}并相应地执行更新。

答案 2 :(得分:0)

虽然这并没有严格回答这个问题 - 我认为它会解决你的需求。问题可能在于分解两个模型来表示一个实体而不是DRF问题。

从Django 1.5开始,你可以创建一个自定义用户,如果你想要的只是一些方法和额外的字段,但除了你对Django用户感到满意之外,你需要做的就是:

class MyUser(AbstractBaseUser): favourite_number = models.IntegerField()

并在设置中:AUTH_USER_MODEL = 'myapp.myuser'

(当然还有db-migration,通过使用db_table选项指向现有用户表并在那里添加新列,可以非常简单。

在那之后,你有DRF擅长的常见案例。