获取Model Serializer中的当前用户

Jam*_*ell 33 python django serialization django-rest-framework

是否可以在模型序列化器中获取当前用户?我想这样做,而不必分离泛型,因为这是一个必须完成的简单任务.

我的模特:

class Activity(models.Model):
    number = models.PositiveIntegerField(
        blank=True, null=True, help_text="Activity number. For record keeping only.")
    instructions = models.TextField()
    difficulty = models.ForeignKey(Difficulty)
    categories = models.ManyToManyField(Category)
    boosters = models.ManyToManyField(Booster)

    class Meta():
        verbose_name_plural = "Activities"
Run Code Online (Sandbox Code Playgroud)

我的序列化器:

class ActivitySerializer(serializers.ModelSerializer):

    class Meta:
        model = Activity
Run Code Online (Sandbox Code Playgroud)

我的观点是:

class ActivityDetail(generics.RetrieveUpdateDestroyAPIView):

    queryset = Activity.objects.all()
    serializer_class = ActivityDetailSerializer
Run Code Online (Sandbox Code Playgroud)

如何返回模型,并附加一个字段user,以便我的响应如下所示:

{
    "id": 1, 
    "difficulty": 1, 
    "categories": [
        1
    ], 
    "boosters": [
        1
    ],
    "current_user": 1 //Current authenticated user here
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*ell 45

我找到了解决DRF源代码的答案.

class ActivitySerializer(serializers.ModelSerializer):

    # Create a custom method field
    current_user = serializers.SerializerMethodField('_user')

    # Use this method for the custom field
    def _user(self, obj):
        request = getattr(self.context, 'request', None)
        if request:
            return request.user

    class Meta:
        model = Activity
        # Add our custom method to the fields of the serializer
        fields = ('id','current_user')
Run Code Online (Sandbox Code Playgroud)

关键是在一个内部定义的方法ModelSerializer可以访问自己的上下文,这些上下文总是包含请求(包含用户在进行身份验证时).由于我的权限仅适用于经过身份验证的用户,因此此处应始终存在一些内容.

这也可以在其他内置的djangorestframework序列化器中完成.

正如Braden Holt指出的那样,如果你user仍然是空的(即_user返回None),可能是因为序列化器没有作为上下文的一部分用请求初始化.要解决此问题,只需在初始化序列化程序时添加请求上下文:

serializer = ActivitySerializer(
    data=request.data,
    context={
        'request': request
    }
)
Run Code Online (Sandbox Code Playgroud)

  • 对于获得请求的每个人KeyError:您可以通过使用请求对象从视图初始化序列化程序来解决此问题,如下所示:serializer = serializers.RandomSerializer(data = request.data,context = {'request':request})Source :http://www.django-rest-framework.org/api-guide/serializers/#saving-instances (2认同)
  • @Braden Holt 谢谢老兄,你为我节省了很多时间 (2认同)

小智 38

上下文在REST框架中传递给序列化程序,默认情况下包含请求.所以你可以self.context['request'].user在你的序列化器里面使用.