根据文档,可以像这样创建和使用自定义权限:
class Task(models.Model):
...
class Meta:
permissions = (
("view_task", "Can see available tasks"),
)
使用权限:
user.has_perm('app.view_task')
来源:https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#custom-permissions
如果权限字符串中存在拼写错误。例如:我使用user.has_perm('app.view_tasks')
,然后就会注意到这个拼写错误。
如果不使用现有权限,我想获得异常或警告。
为了首先避免打字错误,我希望有常量:user.PERM_APP_VIEW_TASKS
或类似的东西。
答案 0 :(得分:2)
从我的has_perm
文件中覆盖ModelBackend
类的backends.py
方法:
import logging
from difflib import get_close_matches
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
class ModelBackendHelper(ModelBackend):
def has_perm(self, user_obj, perm, obj=None):
if not user_obj.is_active:
return False
else:
obj_perms = self.get_all_permissions(user_obj, obj)
allowed = perm in obj_perms
if not allowed:
if settings.DEBUG:
similar = get_close_matches(perm, obj_perms)
if similar:
logging.warn("{0} not found, but is similar to: {1}".format(perm, ','.join(similar)))
return allowed
工作原理:
has_perm
的逻辑相同,但如果settings.DEBUG
为True
且找到perm
的相似版本,则输出级别为WARN
的警告日志消息:< / p>
WARNING:root:myapp.view_tasks not found, but is similar to: myapp.view_task
更改AUTHENTICATION_BACKENDS
中settings.py
的值:
AUTHENTICATION_BACKENDS = ['myapp.backends.ModelBackendHelper']
这可以在生产环境和开发环境中使用,但我个人不会将其包含在生产站点中,我希望当一切都进入生产权限时,合并。
权限属于模型,为了保持这种权限,我重复使用Meta
中定义的权限:
from django.db import models
class Task(models.Model):
name = models.CharField(max_length=30)
description = models.TextField()
class Meta:
permissions = (
("view_task", "Can see available tasks"),
)
def _get_perm(model, perm):
for p in model._meta.permissions:
if p[0] == perm:
return p[0]
err = "Permission '{0}' not found in model {1}".format(perm, model)
raise Exception(err)
def format_perm(perm):
return '{0}.{1}'.format(__package__, perm)
def get_perm(model, type):
return format_perm(_get_perm(model, type))
PERM_APP_VIEW_TASK = get_perm(Task, "view_task")
可以使用get_perm
或快捷方式PERM_APP_VIEW_TASK
访问权限:
models.PERM_APP_VIEW_TASK
# or
get_perm(Task, "view_task")
# or
format_perm(_get_perm(Task, "view_task"))
如果搜索丢失的权限get_perm
,则会引发Exception
:
PERM_APP_VIEW_TASK = get_perm(Task, "add_task")
消息:
Exception: Permission 'add_task' not found in model <class 'myapp.models.Task'>
答案 1 :(得分:0)
创建自定义装饰器:
@permission_required
def assert_permission(permission):
def real_decorator(original_function):
def wrapper(request, *args, **kwargs):
permission_object = Permission.objects.filter(codename=permission)
if not permission_object.exists():
raise ValueError("This permission does not exist!")
original_function(request, *args, **kwargs)
return wrapper
return real_decorator
向模型类添加常量,并在询问特定权限时引用它们。 例如:
class Task(models.Model):
MY_PERMISSION_CONSTANT = 'app.view_task'
...
class Meta:
permissions = (
(MY_PERMISSION_CONSTANT, "Can see available tasks"),
)
@permission_required(Task.MY_PERMISSION_CONSTANT)
def some_view(request):
pass