【问题标题】:DRF: strange behaviour during serialization using "source" in fieldDRF:在字段中使用“源”进行序列化期间的奇怪行为
【发布时间】:2019-09-16 08:30:03
【问题描述】:

型号:

class Profile(models.Model):
    user       = models.ForeignKey(User)
    occupation = models.CharField()

序列化器:

class ProfileSerializer(serializers.ModelSerializer):
    user_id         = serializers.UUIDField(source="user.id")
    user_email      = serializers.EmailField(source="user.email", read_only=True)
    user            = serializers.UserSerializer(read_only=True)

    class Meta:
        model = Profile

当我使用retrieve 操作(即/profiles/1/)点击 API 时,它可以正常工作

示例响应:

{
    "user_id": "user_1",
    "user_email": "human@earth.com",
    "occupation": "software engineer",
    "user": {
         "id": "user_1", "first_name": "", ....
    }
}

但是当我尝试通过提供如下数据来创建资源时:

{
    "user_id": "user_2",
    "occupation": "network engineer"
}

user_id 字段在服务器端变为 {"user": {"uuid": "requested_user_id"}},如下所示:

{
    "user": {
        "uuid": "user_2"
    },
    "occupation": "network engineer",
}

而不是

{
    "user_id": "user_2",
    "occupation": "network engineer",
}

我通过记录serializer.validated_data对此进行了调试。

从 DRF 的角度来看,这是否是期望的行为? 有什么简单的方法可以防止这种情况发生吗? (如字段中的额外 arg 不会更改原始定义的字段名称)

我查看了文档中的core arguments,但没有发现任何帮助。

我只想在视图集下的create 操作中定位user_id

谢谢。

【问题讨论】:

    标签: django django-rest-framework deserialization serialization


    【解决方案1】:

    如下更改您的序列化程序,

    class ProfileSerializer(serializers.ModelSerializer):
        user_id = serializers.UUIDField(source="user.id", read_only=True)
        user_email = serializers.EmailField(source="user.email", read_only=True)
    
        class Meta:
            model = Profile
            fields = '__all__'
            extra_kwargs = {
                'user': {'write_only': True},
            }

    并将创建负载更改为,

    {
        "user": 1,
        "occupation": "network engineer"
    }
    

    其中“1”是数据库中User对象的PK值。

    【讨论】:

    • 好的,我也想在ProfileSerializer下使用user = UserSerializer(read_only=True)。问题是当客户端发送请求以检索配置文件资源时,它应该在配置文件资源下获取用户对象以及 user_id。因此,当他们想要更新配置文件资源时,他们只需在已经提供的有效负载中传递user_id,否则他们必须在发送更新请求之前从最近提供的资源中的user 对象中获取user_id .我怎样才能做到这一点?请查看更新后的问题。
    • 这个答案怎么样,stackoverflow.com/a/52246232/8283848 ??
    • 谢谢,如果我在请求/响应结构中使用该签名,我会考虑它!
    猜你喜欢
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    相关资源
    最近更新 更多