Skip to main content
 首页 » 编程设计

python之自定义对象权限在 django rest 框架中不起作用

2024年10月01日20lyj

我在 django rest APIView 中使用自定义权限类并显式调用 check_object_permissions。但在某些 api(尤其是 retrive api)中,django 默认调用 check_object_permission。如何覆盖 View 以停止对 check_object_permission 的隐式调用。

代码

View .py
    class StreamOptionDetails(APIView): 
        """ 
        Retrieve, update or delete a snippet instance. 
        """ 
 
        permission_classes = (IsOwnerOrReadOnly,) 
 
        def get_object(self, pk): 
            try: 
                obj = Stream.objects.get(pk=pk) 
                self.check_object_permissions(self.request, obj) 
                return obj 
            except Stream.DoesNotExist: 
                raise Http404 
 
        def get_option(self, pk): 
            try: 
                return StreamOption.objects.get(pk=pk) 
            except StreamOption.DoesNotExist: 
                raise Http404 
 
        def get(self, request, stream=None, pk=None, format=None): 
            self.get_object(stream) 
            stream_option = self.get_option(pk) 
            serializer = StreamOptionsSerializer(stream_option) 
            return Response(serializer.data) 

错误

AttributeError at /streams/2/options/15/ 
'StreamOption' object has no attribute 'members' 
    Request Method: GET 
    Request URL:    http://localhost:8000/streams/2/options/15/ 
    Django Version: 1.10 
    Exception Type: AttributeError 
    Exception Value:     
    'StreamOption' object has no attribute 'members 
    Exception Location:  
      /home/suh/workspace/distribution/streams/permissions.py in  
      has_object_permission, line 13 

权限.py
from rest_framework import permissions 
 
 
class IsOwnerOrReadOnly(permissions.BasePermission): 
    """ 
    Custom permission to only allow owners of an object to edit it. 
    """ 
 
    def has_object_permission(self, request, view, obj): 
        # Read permissions are allowed to any request, 
        # so we'll always allow GET, HEAD or OPTIONS requests. 
        if request.user.username   and  request.method in permissions.SAFE_METHODS: 
            members = obj.members.filter(user=request.user) 
            if len(members): 
                return True 
        # Write permissions are only allowed to the owner of the snippet. 
        return obj.owner == request.user 

如何停止调用

File "/home/thoughtchimp/.virtualenvs/django-py3/lib/python3.5/site-    packages/rest_framework/renderers.py" in get_rendered_html_form 
  474.             if not self.show_form_for_method(view, method,     request, instance): 
 
File "/home/thoughtchimp/.virtualenvs/django-py3/lib/python3.5/site-packages/rest_framework/renderers.py" in show_form_for_method 
  431.                 view.check_object_permissions(request, obj) 
 
File "/home/thoughtchimp/.virtualenvs/django-py3/lib/python3.5/site-packages/rest_framework/views.py" in check_object_permissions 
  338.             if not permission.has_object_permission(request,     self, obj): 

请您参考如下方法:

终于得到答案为 StreamOption 添加了新的权限类

权限.py

class IsOwnerOrReadOnlyMember(permissions.BasePermission): 
    """ 
    Custom permission to only allow owners of an object to edit it. 
    """  
 
    def has_object_permission(self, request, view, obj): 
        # Read permissions are allowed to any request, 
        # so we'll always allow GET, HEAD or OPTIONS requests. 
        if not obj.stream: 
            return False 
        obj = obj.stream 
        if not request.user.is_anonymous() and request.method in permissions.SAFE_METHODS: 
            members = obj.members.filter(user=request.user) 
            if len(members): 
                return True 
        # Write permissions are only allowed to the owner of the snippet. 
        return obj.owner == request.user