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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27934822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 02:29:20  来源:igfitidea点击:

Get current user in Model Serializer

pythondjangoserializationdjango-rest-framework

提问by Jamie Counsell

Is it possible to get the current user in a model serializer? I'd like to do so without having to branch away from generics, as it's an otherwise simple task that must be done.

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

My model:

我的型号:

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"

My serializer:

我的序列化器:

class ActivitySerializer(serializers.ModelSerializer):

    class Meta:
        model = Activity

And my view:

而我的观点:

class ActivityDetail(generics.RetrieveUpdateDestroyAPIView):

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

How can I get the model returned, with an additional field usersuch that my response looks like this:

如何使用附加字段返回模型,user使我的响应如下所示:

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

采纳答案by Jamie Counsell

I found the answer looking through the DRF source code.

我通过 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')

The key is the fact that methods defined inside a ModelSerializerhave access to their own context, which always includes the request (which contains a user when one is authenticated). Since my permissions are for only authenticated users, there should always be something here.

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

This can also be done in other built-in djangorestframework serializers.

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

As Braden Holt pointed out, if your useris still empty (ie _useris returning None), it may be because the serializer was not initialized with the request as part of the context. To fix this, simply add the request context when initializing the serializer:

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

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

回答by codwell

A context is passed to the serializer in REST framework, which contains the request by default. So you can just use self.context['request'].userinside your serializer.

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

回答by Andrés M. Jiménez

I modified the request.data:

我修改了 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

回答by Ashen One

I had a similar problem - I tried to save the model that consist user in, and when I tried to use user = serializers.StringRelatedField(read_only=True, default=serializers.CurrentUserDefault())like on official documentation - but it throws an error that user is 'null'. Rewrite the default createmethod and get a user from request helped for me:

我有一个类似的问题 - 我试图保存包含用户的模型,当我尝试user = serializers.StringRelatedField(read_only=True, default=serializers.CurrentUserDefault())在官方文档中使用 like 时 - 但它抛出一个错误,用户是'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