在Django rest框架中使用request.user进行字段级验证 [英] Field level validation with request.user in Django rest framework

查看:213
本文介绍了在Django rest框架中使用request.user进行字段级验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设置Django REST应用程序,人们可以在其中查看餐厅。到目前为止,我有那些模型:

I am setting up a Django REST application where peopple can review restaurants. So far I have those models:

class RestaurantId(models.Model):
    maps_id = models.CharField(max_length=140, unique=True)
    adress = models.CharField(max_length=240)
    name = models.CharField(max_length=140)
        

class RestaurantReview(models.Model):    
    review_author = models.ForeignKey(settings.AUTH_USER_MODEL,
                                      on_delete=models.CASCADE)    
    restaurant_id = models.ForeignKey(RestaurantId, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    

class StarterPics(models.Model):
    restaurant_review_id = models.OneToOneField(RestaurantReview,
                                               on_delete=models.CASCADE)
    pics_author = models.ForeignKey(User, on_delete=models.CASCADE)
    restaurant_id = models.ForeignKey(RestaurantId, on_delete=models.CASCADE)
    name_1 = models.CharField(max_length=40)    
    picture_1 = models.ImageField()

我的序列化器:

class RestaurantIdSerializer(serializers.ModelSerializer):
    class Meta:
        model = RestaurantId
        field = fields = '__all__'


class RestaurantReviewSerializer(serializers.ModelSerializer):
    class Meta:
        model = RestaurantReview
        field = fields = '__all__'


class StarterPicsSerializer(serializers.ModelSerializer):
    class Meta:
        model = StarterPics
        fields = '__all__'

   def validate_restaurant_review_id(self, value)
        if value.review_author != self.request.user:                
            raise serializers.ValidationError("User has not reviewed the restaurant")        
        return value

我的观点:

class RestaurantIdViewset(viewsets.ModelViewSet):
    queryset = models.RestaurantId.objects.all()
    serializer_class = serializers.RestaurantIdSerializer

class RestaurantReviewViewset(viewsets.ModelViewSet):
    queryset = models.RestaurantReview.objects.all()
    serializer_class = serializers.RestaurantReviewSerializer
    permission_classes = [IsAuthenticatedOrReadOnly,IsAuthorOrReadOnly]

    def perform_create(self, serializer):
        serializer.save(review_author=self.request.user)

class StarterPicsViewset(viewsets.ModelViewSet):
    queryset = models.StarterPics.objects.all()
    serializer_class = serializers.StarterPicsSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]
I have set up permissions as well so only the review_author can update his reviews and pics_author can update his pictures.

我的权限:

class IsOwnReviewOrReadOnly(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True

        return obj.pics_author == request.user


class IsAuthorOrReadOnly(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True

    return obj.review_author == request.user

运行Django服务器时,我得到一个'StarterPicsSerializer'对象没有属性'request'

When running Django server I got a 'StarterPicsSerializer' object has no attribute 'request'

此验证适用于尚未撰写评论的用户(review_author),不能在 StarterPics 中发布图片。因此,只有创建评论的用户才能在其上发布图片。

This validation is for user that have not written the review (review_author) can't POST pictures in StarterPics. So only the User that creates the review can post pictures on it.

我也尝试过另一次没有运气的验证:

I've tried another validation with no luck either:

def validate_restaurant_review_id(self, value):               
    if not RestaurantReview.objects.filter(restaurant_review_id=value, 
                     review_author=self.request.user).exists():              
        raise serializers.ValidationError('Not your review')  
    return value


推荐答案

除了要序列化的对象之外,还可以通过在实例化视图中的序列化器时传递上下文参数来为序列化器提供额外的上下文

You could provide extra context to the serializer in addition to the object being serialized by passing a context argument when instantiating the serializer in your view.

serializer = RandomSerializer(instance,context = {'request':request})

如果您使用 通用视图 ModelViewSet (继承自 GenericAPIView ),然后请求已经可用在序列化器中 self.context dict

If you use Generic Views or ModelViewSet(inherited form GenericAPIView), then request is already available in your serializer self.context dict

class StarterPicsSerializer(serializers.ModelSerializer):
    class Meta:
        model = StarterPics
        fields = '__all__'

    def validate_restaurant_review_id(self, value):                     
        print(self.context['request'])

这篇关于在Django rest框架中使用request.user进行字段级验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆