使用Django REST Framework时如何为POST和List等不同方法设置不同的权限';s ListCreateAPIView

使用Django REST Framework时如何为POST和List等不同方法设置不同的权限';s ListCreateAPIView,django,django-rest-framework,Django,Django Rest Framework,我建立了一个Follow模型来记录社交网络行为,并希望模拟以下行为。每个经过身份验证的用户都可以跟随其他用户 class Follow(models.Model): user = models.ForeignKey(User) follower = models.ForeignKey(User, related_name="followers") follow_time = models.DateTimeField(auto_now_add=True, blank=Tru

我建立了一个
Follow
模型来记录社交网络行为,并希望模拟以下行为。每个经过身份验证的用户都可以跟随其他用户

class Follow(models.Model):
    user = models.ForeignKey(User)
    follower = models.ForeignKey(User, related_name="followers")
    follow_time = models.DateTimeField(auto_now_add=True, blank=True)

    class Meta:
        unique_together = ('user', 'follower')

    def __unicode__(self):
        return u'%s, %s' % (self.user.username, self.follower)
FollowSerializer
是:

class FollowSerializer(serializers.ModelSerializer):
    class Meta:
        model = Follow
        field = ('user', 'follower', 'follow_time')
我使用的观点是:

class FollowingEnumByUserID(generics.ListCreateAPIView):
    serializer_class = FollowSerializer

    def get_queryset(self):
        follower_id = self.kwargs['pk']
        return Follow.objects.filter(follower=follower_id)
class IsFollowerOrReadOnly(permissions.BasePermission):
    """
    View-level permission to allow the follower to edit the following relation
    """

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

        try:
            follower = User.objects.get(id=view.kwargs["pk"])
        except User.DoesNotExist:
            #Reject any request for an invalid user
            return False

        return follower == request.user
我在URL中注册它为:

url(r'^api/users/(?P<pk>[0-9]+)/following/$', views.FollowingEnumByUserID.as_view()),
我使用的权限是:

class FollowingEnumByUserID(generics.ListCreateAPIView):
    serializer_class = FollowSerializer

    def get_queryset(self):
        follower_id = self.kwargs['pk']
        return Follow.objects.filter(follower=follower_id)
class IsFollowerOrReadOnly(permissions.BasePermission):
    """
    View-level permission to allow the follower to edit the following relation
    """

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

        try:
            follower = User.objects.get(id=view.kwargs["pk"])
        except User.DoesNotExist:
            #Reject any request for an invalid user
            return False

        return follower == request.user
意见如下:

class FollowingEnumByUserID(generics.ListCreateAPIView):
    serializer_class = FollowSerializer
    permission_class = (IsFollowerOrReadOnly)

    def get_queryset(self):
        """
        List all the people the input user is following
        """
        follower_id = self.kwargs['pk']
        return Follow.objects.filter(follower=follower_id)

class FollowingDelete(generics.DestroyAPIView):
    serializer_class = FollowSerializer
    permission_class = (IsAuthenticated, IsFollowerOrReadOnly)

    def get_queryset(self):
        user_id = self.kwargs['following_id']
        follower_id = self.kwargs['pk']
        return Follow.objects.filter(user=user_id, follower=follower_id)
现在的问题是:

  • 权限类不能完全工作

  • 如何重写
    DestroyAPIView
    ,我是否应该重写
    get\u queryset
    函数

  • Django REST框架,允许您处理视图和对象级别的复杂权限。为了做你想做的事情,你必须这样做,但这非常容易

    每个经过身份验证的用户都可以跟随其他用户

    DRF提供了一个
    IsAuthenticated
    权限,允许您非常轻松地执行此操作。你所要做的就是

    还有另一个限制,它需要自定义权限类

    但是我只想允许经过身份验证的用户自己添加以下关系

    这需要检查请求方法(我假设是
    POST
    )以及被跟踪的用户

    让我们从简单的检查开始,请求方法。Django REST框架提供了检查请求方法的权限类,以便查看它是如何完成的。从这里开始,只需对请求类型进行检查

    class PostIfFollower(BasePermission):
        """
        The request is not POST or the request user is the follower.
        """
    
        def has_permission(self, request, view):
            if request.method != "POST":
                return True
    
            return False
    
    此代码将拒绝使用
    POST
    方法传入的所有请求,同时允许所有其他请求。创建此权限的第二步是进行用户检查,因此只有跟随者可以添加他们正在跟随的新用户。这需要获取跟随者并根据
    请求检查该跟随者。user

        class PostIfFollower(BasePermission):
            """
            The request is not POST or the request user is the follower.
            """
    
            def has_permission(self, request, view):
                if request.method != "POST":
                    return True
    
                try:
                    follower = User.objects.get(id=view.kwargs["pk"])
                except User.DoesNotExist:
                    # Reject any requests for an invalid user
                    return False
    
                return follower == request.user
    

    通过从url获取用户(如果用户不存在,则不允许)并检查他们是否是当前用户,这将建立在上一个权限类的基础上。

    在我修改输入错误后,权限类现在可以工作了:

    class FollowingEnumByUserID(generics.ListCreateAPIView):
        serializer_class = FollowSerializer
        permission_classes = (IsFollowerOrReadOnly,)
    
        def get_queryset(self):
            """
            List all the people the input user is following
            """
            follower_id = self.kwargs['pk']
            return Follow.objects.filter(follower=follower_id)
    
    class FollowingDelete(generics.DestroyAPIView):
        serializer_class = FollowSerializer
        permission_classes = (IsAuthenticated, IsFollowerOrReadOnly,)
    
        def get_queryset(self):
            user_id = self.kwargs['following_id']
            follower_id = self.kwargs['pk']
            return Follow.objects.filter(user=user_id, follower=follower_id)
    
    通过覆盖
    get\u object()
    函数,我使
    followdelete
    视图成功工作

    def get_object(self, *args, **kwargs):
        user_id = self.kwargs['following_id']
        follower_id = self.kwargs['pk']
    
        try:
            return Follow.objects.get(user=user_id, follower=follower_id)
        except Follow.DoesNotExist:
            raise Http404("No such following relation")
    

    你好,@Kevin,你能回答上面更新过的问题吗?@Scofield77乍一看,你修改过的代码似乎适合你正在尝试的操作。我建议不要修改这个,因为它似乎是一个不同的问题。另外,欢迎使用堆栈溢出!