【问题标题】:Django Rest Framework Permissions not being called for Detail and List View没有为详细信息和列表视图调用 Django Rest Framework 权限
【发布时间】:2020-05-27 04:45:15
【问题描述】:

我创建了这个自定义权限类,当我从视图发出请求时,它似乎没有被调用。我将其设置为返回 false 并且请求仍然成功。尝试放置打印语句以查看是否有任何输出但没有。不知道我在做什么。

查看:

class EventEditView(RetrieveUpdateDestroyAPIView):
    authentication_classes = (SessionAuthentication, JSONWebTokenAuthentication,  )
    permission_classes = (EventVisibilityPerm, )
    serializer_class = EventEditSerializer

    def get(self, request, *args, **kwargs):
        event = get_object_or_404(Event, slug=kwargs['slug'])
        serializer = EventSerializer(event)
        return Response(serializer.data)

Permissions.py:

class EventVisibilityPerm(permissions.BasePermission):
    """
    Permission class determines whether a user has access to a specific Event
    """

def has_object_permission(self, request, view, obj):
    user = request.user
    if obj.user == user:
        return True

**序列化器:**

class EventSerializer(serializers.ModelSerializer):
    class Meta:
        model = Event
        exclude = ('user', 'id')

目前正在测试此详细视图的权限,但此权限也需要用于列表视图。

【问题讨论】:

  • 看来你应该把 authentication_classes
  • 出于测试目的,我将其留空。

标签: django django-rest-framework django-views django-permissions


【解决方案1】:

必须在创建自定义权限类时实现has_permission(self, request, view)方法。

来自DRF Doc

只有在视图级别的has_permission检查已经通过时,才会调用实例级别的has_object_permission方法。

示例:

from rest_framework import permissions


class EventVisibilityPerm(permissions.BasePermission):
    def has_permission(self, request, view):
        """
        allowing users with specific email ids
        """
        if request.user.email in EMAIL_WHITELIST:
            return True
        return False

    def has_object_permission(self, request, view, obj):
        """
        allowing users those who are the owner of the object (obj.user)
        """
        return request.user == obj.user

【讨论】:

  • 我明白了,那么使用 has_permission 方法检查对象级别值的适当方法是什么?
  • 在您的EventVisibilityPerm 类中实现has_permission 方法,以便它应该处理您的自定义权限检查。就是这样
  • 是否有不需要为 ListAPI 的查询集中的每个对象使用 forloop 的实现?
  • has_object_permission 方法仅在Detail View API 调用期间被调用。无论如何,我添加了一个简单的示例,希望对您有所帮助
  • 如果你想限制ListAPI中显示的对象/实例,你应该重写get_queryset()方法看法。正如我之前所说,has_object_permission 方法仅适用于 Detail View,每个 API 调用仅处理一个对象
【解决方案2】:

您可以覆盖权限类的两个函数,您继承自BasePermission。这些函数是has_permissionhas_object_permissionhas_permission 会自动检查。但has_object_permission 函数应在您的视图中手动调用,代码如下:

self.check_object_permissions(self.request, obj)

【讨论】:

  • 我明白了,如何检查对象查询集的权限?我会想象为集合中的每个对象使用 forloop 会非常低效。
  • 如果可能,您可以使用 Django ORM 功能检查查询集中的条件。
猜你喜欢
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-22
  • 2016-04-14
  • 1970-01-01
  • 2017-03-06
  • 2014-09-08
相关资源
最近更新 更多