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

时间:2017-08-19 10:20:20

标签: python django django-rest-framework

我在django rest APIView中使用自定义权限类并明确调用 check_object_permissions 。但是在某些api(特别是在retrive api中)django默认调用 check_object_permission 。如何覆盖视图以停止对 check_object_permission 的隐式调用。

代码

views.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

permission.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):

1 个答案:

答案 0 :(得分:2)

最终为StreamOption添加了新的权限类

permission.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