获取Model Serializer中的当前用户

时间:2015-01-14 02:16:43

标签: 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"

我的序列化器:

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
}

4 个答案:

答案 0 :(得分:40)

我找到了解决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')

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

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

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

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

答案 1 :(得分:31)

在REST框架中将上下文传递给序列化程序,默认情况下包含请求。因此,您只需在序列化程序中使用self.context['request'].user

答案 2 :(得分:0)

我遇到了类似的问题-我尝试保存包含用户的模型,并尝试使用 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

答案 3 :(得分:-2)

我修改了request.data:

JQuery(function($) {
  $(document).on('turbolinks:load', function() {
    $('.time').clockTimePicker();
  });
});