需要 Django 权限

Django Permission Required

我正在尝试检查某些 API 请求的权限。 我已经设置了 auth 用户和 auth_user_user_permissions 和 auth_permissions 表,例如 view_company add_company bla bla,但问题不在于此。问题是当我尝试使用 decorator which

@permission_required('API.view_company', raise_exception=True)

它对我说

AttributeError: 'CompanyDetailView' object has no attribute 'user'

很可能它正在寻找用户,因为它会检查 user_permission 是否可以查看公司,但我在 urls.py 中声明的视图(路径('companies//', CompanyDetailView.as_view()),) 没有用户对象,这就是为什么错误消息返回属性错误,我该如何解决,非常感谢

我尝试在视图 class 中设置示例用户,一开始,它起作用了,因为视图正在寻找用户对象,我不能那样使用,因为每个请求都有不同的用户

import rest_framework
from rest_framework import status
from django.contrib.auth.models import User
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth.decorators import permission_required

class CompanyDetailView(APIView):
    @permission_required('api.view_company', raise_exception=True)
    def get(self, request, id):
        try:
            request_data = {}
            request_data['request_method'] = request.method
            request_data['id'] = id
            companies = Company.objects.get(id=id)
            status = rest_framework.status.HTTP_200_OK
            return Response(companies, status)

bla bla bla

url 行是 =

path('companies/<int:id>/', CompanyDetailView.as_view()),

我的错误信息是:AttributeError: 'CompanyDetailView' object has no attribute 'user'

当我调试时看到 request.user.has_perm('view_company') 返回错误但仍然 api 给出响应,它假设说你不允许查看公司

根据描述permission_required,这个装饰器应该用于函数视图,其中第一个参数是 request 并且您尝试将它应用于第一个参数的 class 方法在 CompanyDetailView 的实例中,参数是 self 所以你得到了错误。并且您应该使用其他方式来检查权限。

您可以在此处阅读一些示例:decorators-on-django-class-based-views

您无法通过 django rest 框架轻松使用 django 权限。

有一个关于 django-rest-framework 权限的教程:

https://www.django-rest-framework.org/api-guide/permissions/

Django Views 和 Django Rest Framework Views 的机制有点不同,这就是您收到该错误消息的原因。 permission_required 将尝试访问您视图的 user 字段,以使用 has_perm 方法检查用户权限。但是 APIView 里面没有 user 字段。

要摆脱这种情况,您可能需要使用 Django Rest Framework 提供的 permissions 来限制访问。

但是如果您仍然想使用 Django 的内置权限来限制对您的视图的访问,您可以创建一个权限 class,它将使用 has_perm 检查用户权限。像这样:

from rest_framework import permissions
from rest_framework import exceptions

class ViewCompanyPermission(permissions.BasePermission):
    def has_permission(self, request, view):
        if not request.user.has_perm('api.view_company'):
            raise exceptions.PermissionDenied("Don't have permission")
        return True

并通过 permission_classes 字段在您的视图中使用它:

class CompanyDetailView(APIView):
    permission_classes = (ViewCompanyPermission, )
    def get(self, request, id):
        try:
            request_data = {}
            request_data['request_method'] = request.method
            request_data['id'] = id
            companies = Company.objects.get(id=id)
            status = rest_framework.status.HTTP_200_OK
            return Response(companies, status)

如果您想复制 permission_required 行为,您可以这样做:

from rest_framework import permissions
from rest_framework import exceptions

def permission_required(permission_name, raise_exception=False):
    class PermissionRequired(permissions.BasePermission):
        def has_permission(self, request, view):
            if not request.user.has_perm(permission_name):
                if raise_exception:
                    raise exceptions.PermissionDenied("Don't have permission")
                return False
            return True
    return PermissionRequired

然后你可以像这样使用它:

class CompanyDetailView(APIView):
    permission_classes = (permission_required("api.view_company", raise_exception=True), )
    # ...