【问题标题】:How do I properly provide user field to ModelSerializer in Django Rest Framwork如何在 Django Rest Framework 中为 ModelSerializer 正确提供用户字段
【发布时间】:2019-07-26 16:46:51
【问题描述】:

我有一个 django Profile 模型:

class Profile(models.Model):
    created_by = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    name = models.CharField(max_length=100, blank=True)
    meta = models.TextField(blank=True)

    def __str__(self):
        return self.created_by

还有一个序列化程序(我知道目前做的不多)

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = '__all__'

在我的更新方法中,我似乎永远无法验证序列化程序。

这就是我要做的事情:

profile = Profile()
profile.created_by = request.user
serializer = ProfileSerializer(profile)

serializer.is_valid() 总是返回 False。顺便说一句,request.user 是经过身份验证的CustomUser

我也试过设置

serializer = ProfileSerializer(
                              instance=profile,
                              data={'created_by':request.user}
                              )

以及它们的许多组合。我错过了什么无法验证序列化程序?显然这里的用户有一些问题。

补充:我是 DRF 的新手,为什么 DRF 似乎知道用户是谁时默认设置“created_by”字段?

【问题讨论】:

  • 您是否尝试打印serializer.errors
  • 嘿@AbdulNiyasPM 是的。当我将created_by 字段作为request.user 传递时,我得到{'created_by': [ErrorDetail(string='This field is required.', code='required')]},我得到{'created_by': [ErrorDetail(string='Incorrect type. Expected pk value, received CustomUser.', code='incorrect_type')]}
  • 我猜data={'created_by':request.user.id} 会解决这个问题。

标签: python django serialization django-rest-framework


【解决方案1】:

如果你想将created_by字段自动设置为只读,使用户无法编辑该字段,在你的ProfileSerializer中,可以使用DRF提供的CurrentUserDefault class。然后您不必担心在视图中显式更新您的用户。

如下所示:

from rest_framework import serializers

class ProfileSerializer(serializers.ModelSerializer):
created_by = serializers.HiddenField(
    default=serializers.CurrentUserDefault()
)

    class Meta:
        model = Profile
        fields = '__all__'

CurrentUserDefault 所做的基本上是来自序列化程序上下文中包含的请求的retrieve the authenticated user

class CurrentUserDefault(object):
    def set_context(self, serializer_field):
        self.user = serializer_field.context['request'].user

    def __call__(self):
        return self.user

【讨论】:

    猜你喜欢
    • 2021-08-08
    • 2020-06-27
    • 1970-01-01
    • 2013-01-13
    • 2020-07-29
    • 2013-08-26
    • 2017-03-21
    • 2017-03-05
    相关资源
    最近更新 更多