有没有办法在django中执行行级权限?我以为没有,只是在文档中注意到了这一点:
不仅可以为每种类型的对象设置权限,还可以设置per 特定的对象实例。通过使用has_add_permission(), 提供了has_change_permission()和has_delete_permission()方法 通过ModelAdmin类,可以自定义权限 不同的相同类型的对象实例。
https://docs.djangoproject.com/en/dev/topics/auth/
但我没有看到任何关于如何实际实现每个实例权限的文档
答案 0 :(得分:25)
对于我正在构建的应用程序,我想通过一个简单的装饰器提供行级权限。我可以这样做,因为条件是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:
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
感谢任何反馈或评论。
Paul Bormans
答案 1 :(得分:6)
管道就在那里(这是你链接的同一页面的底部):
处理对象权限
Django的权限框架有一个 对象权限的基础,虽然没有实现 因为它在核心。这意味着检查对象权限 将始终返回False或空列表(取决于检查 执行)。身份验证后端将接收关键字 参数obj和user_obj用于每个对象相关的授权 方法,并可以适当返回对象级别权限。
但是没有提供默认实现。因为这是一个共同话题; SO上有很多answers。检查右侧,你会看到一些列出。
基本思想是浏览django packages' perm grid并选择对象级权限的实现。我个人喜欢django-guardian。
答案 2 :(得分:6)
文档讨论的方法将允许您限制对admin中特定对象的访问。每个方法都通过播放中的对象传递,您可以通过返回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
答案 3 :(得分:1)
我已经使用Django Class Based Views推出了解决这类问题的方法。
查看我的文章Django Generic Class Based Views with Object-Level Permissions Checking。
答案 4 :(得分:0)
django available on PyPi有大量“权限”应用 例如,您可以查看django-object-permission。
文档所指的是实现权限的功能。人们通过为此创建应用程序就是这样做的。