Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django REST框架-允许工作人员访问所有端点_Python_Django_Permissions_Django Rest Framework - Fatal编程技术网

Python Django REST框架-允许工作人员访问所有端点

Python Django REST框架-允许工作人员访问所有端点,python,django,permissions,django-rest-framework,Python,Django,Permissions,Django Rest Framework,我正在构建一个DRFAPI,我希望允许工作人员(is_staff==True)访问所有REST端点,同时仍为每个视图集提供自定义权限检查。理想情况下,这将是一个全局设置,但我不反对按视图集设置 以下是我尝试过的一些事情: 选项1:检查每个自定义权限 来自rest\u框架的导入权限 类SomeModelPermission(permissions.BasePermission): def具有_权限(自我、请求、查看): 如果request.user.is_员工: 返回真值 #其他逻辑 def具有

我正在构建一个DRFAPI,我希望允许工作人员(
is_staff==True
)访问所有REST端点,同时仍为每个视图集提供自定义权限检查。理想情况下,这将是一个全局设置,但我不反对按视图集设置

以下是我尝试过的一些事情:


选项1:检查每个自定义权限
来自rest\u框架的导入权限
类SomeModelPermission(permissions.BasePermission):
def具有_权限(自我、请求、查看):
如果request.user.is_员工:
返回真值
#其他逻辑
def具有对象权限(自我、请求、查看、obj):
如果request.user.is_员工:
返回真值
#其他逻辑
这是可行的,但我不想重复这么多代码


选项2:按位运算符 我尝试从上面的自定义权限中删除
is_staff
逻辑,并将其添加到视图集中:

来自rest\u框架的导入权限、视图集
类SomeModelViewSet(viewsets.ModelViewSet):
permission_classes=(permissions.isadmin用户| SomeModelPermission,)
但是,这实际上并没有像我所希望的那样强制执行权限,因为
isadmin用户
继承自
BasePermission
,其定义如下:

类基本权限(对象):
def具有_权限(自我、请求、查看):
返回真值
def具有对象权限(自我、请求、查看、obj):
返回真值
isadmin用户
没有定义自己的
拥有\u object\u权限
,因此在检查对象权限时,它将始终返回
True
,从而导致意外的对象访问


有什么想法吗?我希望有某种方法可以设置全局权限检查,当用户是工作人员时,该检查将返回
True
,否则将遵从自定义权限。但通读一遍,我不确定这是否可行。

按位解决方案: 如何创建您自己的
isadmin用户
,该用户还定义了
具有对象权限
?您可以从现有的继承:

从rest\u framework.permissions将isadmin导入为baseisadmin用户
类IsAdminUser(BaseIsAdminUser):
def具有对象权限(自我、请求、查看、obj):
#只需重复使用与“has_permission”相同的逻辑即可。。。
返回self.has_权限(请求、查看)
然后,可以使用位运算符执行上面尝试的操作:

来自rest\u框架的导入权限、视图集
从您自己的\u项目中导入权限IsAdminUser
类SomeModelViewSet(viewsets.ModelViewSet):
权限_类=(IsAdminUser | SomeModelPermission,)

另一个解决方案: 在某些方面有点“黑客”,但您可以尝试动态创建自己的权限类型

因此,最终结果将类似于:

class SomeModelViewSet(ViewSet.ModelViewSet):
权限\类=跳过\人员的权限((SomeModelPermission,SomeOtherPermission,…)
实现类似于:

类StaffAllowedMixin:
def具有_权限(自我、请求、查看):
如果request.user.is_员工:
返回真值
return super().具有权限(请求、查看)
def具有对象权限(自我、请求、查看、obj):
如果request.user.is_员工:
返回真值
return super().具有\对象\权限(请求、视图、对象)
def skip_适用于_员工(权限类):
#您也可以在此处使用理解,但为了清楚起见:
职员允许的班级=[]
在permissions中查找permission\u类(
职员\u允许\u类。追加(
#创建名为StaffAllowed的新类型(类)
键入(f“StaffAllowed{permission_class}”,
#从上面的mixin和原始类继承
(StaffAllowedMixin,许可等级),
#空字典表示您不想覆盖任何属性
{})
)
返回元组(人员\u允许\u类)
基本上,对于每个权限类,您都会创建一个具有额外mixin的新类,该类具有优先权并检查用户是否为staff。
但是您可以在使用权限的情况下动态地执行此操作,而不必为每个权限预定义权限。

有一个管理员用户权限类。 以下是一个例子:

class deletecompletedreopenjobAPIView(RetrieveUpdateAPIView):
    queryset = Job.objects._all()
    serializer_class = JobCompletedDeleteStatusSerializer
    lookup_field = 'job_id'
    permission_classes = [IsOwnerOrReadOnly | **IsAdminUser**]
    authentication_classes = (authentication.TokenAuthentication,)
我的自定义IsownerReadOnly如下所示:

class IsOwnerOrReadOnly(BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in SAFE_METHODS:
            return True
        return obj.user == request.user