向Django管理添加权限
上个月我在StackOverflow和Django用户组的G+上,以及Django官网上发了个问题,但没有找到能解决我问题的答案。我想在Django的管理面板里添加一个新的权限,叫做view
,这样用户就只能查看数据了!我还尝试过Django官网上的不同补丁,也试过django-databrowse
,但都没有达到预期效果。最后我决定编辑auth/admin
的视图。接下来我打算像这样添加查看权限:
1. 在默认权限列表中添加'view'
#./contrib/auth/management/init.py
def _get_all_permissions(opts):
"Returns (codename, name) for all permissions in the given opts."
perms = []
for action in ('add', 'change', 'delete', 'view'):
perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
return perms + list(opts.permissions)
2. 测试'view'权限是否已添加到所有模型中
run manage.py syncdb
这样之后,我就可以只给用户分配查看权限了。现在这个查看权限也必须能正常工作。所以我在django-admin
的view.py
里写了这段代码:
for per in request.user.user_permissions_all():
print per
这段代码会打印出登录用户被分配的权限,比如auth | permission | can view department
等等。
现在我可以通过拆分这个句子来获取权限类型和模型名称。我会得到应用程序的所有模型名称,并匹配哪些数据应该可见。不过这并不是我真正需要的,但可以用。
所以我想问的是:
* 这样做是否正确,或者还有其他方法?我只想要一个能正常工作的解决方案。需要你的帮助 *
1 个回答
给默认权限列表添加'查看'权限
你的解决方案是可行的,但尽量不要直接修改源代码。其实有几种方法可以在框架内实现这个功能:
1. 在 post_syncdb()
时添加权限:
在你的应用的管理文件夹下创建一个文件:
from django.db.models.signals import post_syncdb
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import Permission
def add_view_permissions(sender, **kwargs):
"""
This syncdb hooks takes care of adding a view permission too all our
content types.
"""
# for each of our content types
for content_type in ContentType.objects.all():
# build our permission slug
codename = "view_%s" % content_type.model
# if it doesn't exist..
if not Permission.objects.filter(content_type=content_type, codename=codename):
# add it
Permission.objects.create(content_type=content_type,
codename=codename,
name="Can view %s" % content_type.name)
print "Added view permission for %s" % content_type.name
# check for all our view permissions after a syncdb
post_syncdb.connect(add_view_permissions)
每当你执行'syncdb'命令时,系统会检查所有内容类型是否有'查看'权限,如果没有,就会创建一个。
- 来源: Nyaruka博客
2. 将权限添加到 Meta权限选项:
在每个模型下,你需要在它的Meta
选项中添加类似这样的内容:
class Pizza(models.Model):
cheesiness = models.IntegerField()
class Meta:
permissions = (
('view_pizza', 'Can view pizza'),
)
这样做的效果和1是一样的,只不过你需要手动为每个类添加。
3. 在Django 1.7中新增,将权限添加到 Meta默认权限选项:
在Django 1.7中,他们增加了default_permissions这个Meta选项。在每个模型下,你需要将'查看'添加到default_permissions选项中:
class Pizza(models.Model):
cheesiness = models.IntegerField()
class Meta:
default_permissions = ('add', 'change', 'delete', 'view')
测试'查看'权限是否添加到所有模型
至于测试用户是否拥有该权限,你可以使用has_perm()
函数进行测试。例如:
user.has_perm('appname.view_pizza') # 如果用户'可以查看披萨',则返回True