django中的行级权限

9-b*_*its 17 django django-models django-permissions

有没有办法在django中进行行级权限?我以为没有,只是在文档中注意到了这一点:

权限不仅可以针对每种类型的对象进行设置,还可以针对特定对象实例进行设置.通过使用ModelAdmin类提供的has_add_permission(),has_change_permission()和has_delete_permission()方法,可以为同一类型的不同对象实例自定义权限.

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

但我没有看到任何关于如何实际实现每个实例权限的文档

Pau*_*ans 26

对于我正在构建的应用程序,我想通过一个简单的装饰器提供行级权限.我可以这样做,因为条件只是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
Run Code Online (Sandbox Code Playgroud)

风景:

@login_required
@is_owner_permission_required(Comment)
def edit_comment(request, pk):
    ...
Run Code Online (Sandbox Code Playgroud)

网址:

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

该模型:

class Comment(models.Model):
    user = models.ForeignKey(User, ...
    <...>
    def is_owner(self, user):
        return self.user == user
Run Code Online (Sandbox Code Playgroud)

任何反馈或评论都表示赞赏.

保罗博尔曼斯


Bur*_*lid 6

管道就在那里(这是你链接的同一页面的底部):

处理对象权限

Django的权限框架具有对象权限的基础,尽管在核心中没有实现它.这意味着检查对象权限将始终返回False或空列表(取决于执行的检查).身份验证后端将为每个与对象相关的授权方法接收关键字参数obj和user_obj,并且可以根据需要返回对象级别权限.

但是没有提供默认实现.因为这是一个共同话题; SO上有很多答案.检查右侧,你会看到一些列出.

基本思想是浏览django包的perm网格并选择对象级权限的实现.我个人喜欢django-guardian.


Chr*_*att 6

文档讨论的方法将允许您限制对管理员中特定对象的访问.每个方法都通过播放中的对象传递,您可以通过返回True或使用它来确定用户是否可以访问它False.

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
Run Code Online (Sandbox Code Playgroud)


jdi*_*jdi 0

PyPi 上有大量 django 的“权限”应用程序,
例如您可以查看django-object-permission

文档所指的是实现权限的功能。人们已经通过为此创建应用程序来做到这一点。