在Django行级权限(row level permissions in django)

2019-07-30 21:05发布

有没有办法做到行级权限在Django? 我觉得有不只是注意到这一点的文档:

权限不仅可以每个类型的对象进行设置,而且每个特定对象实例。 通过使用has_add_permission(),has_change_permission()和has_delete_permission()方法由的ModelAdmin类提供,能够定制权限相同类型的不同对象实例。

https://docs.djangoproject.com/en/dev/topics/auth/

但我没有看到如何实际每个实例的权限执行任意文件

Answer 1:

对于应用程序我建设我想通过一个简单的装饰,以提供行级别的权限。 因为条件是request.user仅仅是模型对象的所有者我可以做到这一点。

以下似乎工作:

from functools import wraps
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist

def is_owner_permission_required(model, pk_name='pk'):
    def decorator(view_func):
        def wrap(request, *args, **kwargs):
            pk = kwargs.get(pk_name, None)
            if pk is None:
                raise RuntimeError('decorator requires pk argument to be set (got {} instead)'.format(kwargs))
            is_owner_func = getattr(model, 'is_owner', None)
            if is_owner_func is None:
                raise RuntimeError('decorator requires model {} to provide is_owner function)'.format(model))
            o=model.objects.get(pk=pk) #raises ObjectDoesNotExist
            if o.is_owner(request.user):
                return view_func(request, *args, **kwargs)
            else:
                raise PermissionDenied
        return wraps(view_func)(wrap)
    return decorator

风景:

@login_required
@is_owner_permission_required(Comment)
def edit_comment(request, pk):
    ...

网址:

url(r'^comment/(?P<pk>\d+)/edit/$', 'edit_comment'),

该模型:

class Comment(models.Model):
    user = models.ForeignKey(User, ...
    <...>
    def is_owner(self, user):
        return self.user == user

任何意见或言论表示赞赏。

保罗·鲍彻



Answer 2:

该管道是有(这是从你连接的同一个页面的底部):

处理对象权限

Django的许可框架对对象权限的基础上,虽然有核心没有它。 这意味着,检查对象的权限将总是返回false或空列表(取决于执行的检查)。 的认证的后端将接收关键字参数obj和USER_OBJ为每个对象相关的授权方法和可以返回该对象的权限级别适当。

但是,没有缺省实现提供。 由于这是一个共同的话题; 有很多的答案对SO。 检查的权利,你会看到一些上市。

基础思想是浏览Django的软件包的烫发电网并挑选的对象级权限的实现。 我个人比较喜欢的Django监护人 。



Answer 3:

该文档谈这些方法可以让你限制访问特定对象的管理。 每一种方法是通过在游戏中的对象,你可以用它来做出关于用户是否可以访问它,通过返回无论是确定TrueFalse

class MyModelAdmin(admin.ModelAdmin):
    ...
    def has_add_permission(self, request):
        # This one doesn't get an object to play with, because there is no
        # object yet, but you can still do things like:
        return request.user.is_superuser
        # This will allow only superusers to add new objects of this type

    def has_change_permission(self, request, obj=None):
        # Here you have the object, but this is only really useful if it has
        # ownership info on it, such as a `user` FK
        if obj is not None:
            return request.user.is_superuser or \
                   obj.user == request.user
            # Now only the "owner" or a superuser will be able to edit this object
        else:
            # obj == None when you're on the changelist page, so returning `False`
            # here will make the changelist page not even viewable, as a result,
            # you'd want to do something like:
            return request.user.is_superuser or \
                   self.model._default_manager.filter(user=request.user).exists()
            # Then, users must "own" *something* or be a superuser or they
            # can't see the changelist

    def has_delete_permission(self, request, obj=None):
        # This pretty much works the same as `has_change_permission` only
        # the obj == None condition here affects the ability to use the
        # "delete selected" action on the changelist


Answer 4:

我已经转出的解决方案使用基于Django的类视图这样那样的问题。

看看我的文章的Django泛型类为本次用对象级权限检查 。



Answer 5:

有大量的“权限” Django的应用程序上可用的PyPI
例如,你可以看一下Django的对象的权限 。

什么文档指的是该功能是有执行权限。 而人们也通过创建这个应用程序做到了这一点。



文章来源: row level permissions in django