在模型序列化器中获取当前用户

Get current user in Model Serializer

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

我的模特:

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"

我的序列化器:

class ActivitySerializer(serializers.ModelSerializer):

    class Meta:
        model = Activity

我的观点:

class ActivityDetail(generics.RetrieveUpdateDestroyAPIView):

    queryset = Activity.objects.all()
    serializer_class = ActivityDetailSerializer

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

{
    "id": 1, 
    "difficulty": 1, 
    "categories": [
        1
    ], 
    "boosters": [
        1
    ],
    "current_user": 1 //Current authenticated user here
}

我通过 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 = self.context.get('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')

关键是 ModelSerializer 中定义的方法可以访问它们自己的上下文,该上下文始终包含请求(其中包含经过身份验证的用户)。由于我的权限仅适用于经过身份验证的用户,因此这里应该总是有一些东西。

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

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

serializer = ActivitySerializer(
    data=request.data,
    context={
        'request': request
    }
)

REST framework 中的序列化器传递了一个上下文,默认情况下包含请求。所以你可以在你的序列化器中使用 self.context['request'].user

我修改了request.data:

serializer = SectionSerializer(data=add_profile_data(request.data, request.user))

def add_profile_data(data, user):
    data['user'] = user.profile.id
    return data

我有一个类似的问题 - 我试图保存包含用户的模型,当我尝试使用 user = serializers.StringRelatedField(read_only=True, default=serializers.CurrentUserDefault()) 就像官方文档一样 - 但它会抛出用户是 'null' 的错误。重写默认的 create 方法并从对我有帮助的请求中获取用户:

class FavoriteApartmentsSerializer(serializers.ModelSerializer):
user = serializers.StringRelatedField(read_only=True, default=serializers.CurrentUserDefault())

class Meta:
    model = FavoriteApartments
    exclude = (
        'date_added',
    )

def create(self, validated_data):
    favoriteApartment = FavoriteApartments(
        apartment=validated_data['apartment'],
        user=self.context['request'].user
    )
    favoriteApartment.save()
    return favoriteApartment