row level permissions in django

后端 未结 5 1993
一个人的身影
一个人的身影 2021-01-30 15:19

Is there a way to do row level permissions in django? I thought there wasn\'t but just noticed this in the docs:

Permissions can be set not only per type

5条回答
  •  忘掉有多难
    2021-01-30 15:38

    For an application i'm building i want to provide row level permission through a simple decorator. I can do this because the condition is just whether the request.user is the owner of the model object.

    Following seems to work:

    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
    

    The view:

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

    Urls:

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

    The model:

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

    Any feedback or remarks are appreciated.

    Paul Bormans

提交回复
热议问题