定义现有用户查看或修改其他用户的权限
Define permissions to existing users for viewing or modifying other users
我目前正在学习 Django 中的权限框架,我希望为用户定义一组权限,定义他们是否可以查看或修改系统中的其他用户。
我在多模式数据库上使用 django.auth
框架,其中每个模式都有自己的一组用户。
我想从本质上应用它,但要应用到内置用户 model
。
class Meta:
permissions = (
("can_view_users", "Can view all users"),
("can_modify_users", "Can modify all users"),
("can_password_reset_users", "Can reset passwords for all users"),
("can_delete_users", "Can delete all users"),
)
但是我似乎找不到任何关于将此逻辑应用于内置身份验证框架的文档。
我已经通过部署我自己的许可 app
解决了这个问题。我仍然通过内置框架创建和管理用户和会话,但是使用我自己的 model
来管理用户权限。
它按我的预期工作,让我可以从每个用户的角度自定义尽可能多的内容。
步骤
- 创建名为
users
的用于管理权限的新应用
- 创建一个名为
Permissions
的模型,其中 ForeignKey
到 AUTH_USER_MODEL
- 创建自定义装饰器以检查用户调用视图的权限
- 将装饰器应用于视图,指定视图需要哪些权限
此时,如果用户没有指定的权限,则无法使用页面。这很好,就好像用户尝试 post
到 users/new
他们的服务器将响应 HTTP 503
.
下一个问题是修改基本模板,以便用户只能看到允许他们看到的菜单选项。我通过使用自定义 context_processor
.
实现了这一点
- 创建自定义
context_processor
,它利用 Permissions
user_has_perms
检索已验证用户的所有权限。
- 将处理器添加到
settings.py
- 利用
djangos
模板处理呈现用户有权访问的字段
代码
model
权限
class Permissions(models.Model):
permission_id = models.AutoField(primary_key=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
## User Management ##
can_user_view_staff = models.BooleanField(default = False)
def user_has_perms(user, perm):
user_exists = Permissions.objects.filter(user_id=user).count()
if user_exists:
if perm == None:
## if no permission specified, return all permissions for user ##
return Permissions.objects.filter(user_id=user)
else:
return Permissions.objects.filter(user_id=user).values(perm).last()[perm]
else:
return False
decorator
授权
from django.http import HttpResponseForbidden
from apps.users.models import user_has_perms
## Check if user has permission to load page ##
def authorization_required(permissions=''):
def decorator(view):
def wrapper(request, *args, **kwargs):
can_user = user_has_perms(request.user, permissions)
if can_user or request.user.is_superuser:
return view(request, *args, **kwargs)
else:
return HttpResponseForbidden()
return wrapper
return decorator
views
使用装饰器查看
from decorators.authorization import authorization_required
@login_required
@authorization_required('can_user_view_staff')
def users(request):
user_model = get_user_model()
user_list = user_model.objects.all()
context = {
'users': user_list
}
return render(request, 'users/users.html', context)
context_processor
from apps.users.models import user_has_perms
def permissions(request):
if request.user.is_authenticated:
user_perms = user_has_perms(request.user, None)
else:
user_perms = None
return {
'user_perms': user_perms
}
修改settings.py
添加新处理器
TEMPLATES = [
{
'OPTIONS': {
'context_processors': [
'context_processors.perm_context.permissions',
],
},
},
]
更新 base.html 以在呈现字段之前检查用户权限
{% if user_perms.can_user_view_staff or request.user.is_superuser %}
<a class="dropdown-item" href="/users">User Management</a>
{% endif %}
我目前正在学习 Django 中的权限框架,我希望为用户定义一组权限,定义他们是否可以查看或修改系统中的其他用户。
我在多模式数据库上使用 django.auth
框架,其中每个模式都有自己的一组用户。
我想从本质上应用它,但要应用到内置用户 model
。
class Meta:
permissions = (
("can_view_users", "Can view all users"),
("can_modify_users", "Can modify all users"),
("can_password_reset_users", "Can reset passwords for all users"),
("can_delete_users", "Can delete all users"),
)
但是我似乎找不到任何关于将此逻辑应用于内置身份验证框架的文档。
我已经通过部署我自己的许可 app
解决了这个问题。我仍然通过内置框架创建和管理用户和会话,但是使用我自己的 model
来管理用户权限。
它按我的预期工作,让我可以从每个用户的角度自定义尽可能多的内容。
步骤
- 创建名为
users
的用于管理权限的新应用
- 创建一个名为
Permissions
的模型,其中ForeignKey
到AUTH_USER_MODEL
- 创建自定义装饰器以检查用户调用视图的权限
- 将装饰器应用于视图,指定视图需要哪些权限
此时,如果用户没有指定的权限,则无法使用页面。这很好,就好像用户尝试 post
到 users/new
他们的服务器将响应 HTTP 503
.
下一个问题是修改基本模板,以便用户只能看到允许他们看到的菜单选项。我通过使用自定义 context_processor
.
- 创建自定义
context_processor
,它利用Permissions
user_has_perms
检索已验证用户的所有权限。 - 将处理器添加到
settings.py
- 利用
djangos
模板处理呈现用户有权访问的字段
代码
model
权限
class Permissions(models.Model):
permission_id = models.AutoField(primary_key=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
## User Management ##
can_user_view_staff = models.BooleanField(default = False)
def user_has_perms(user, perm):
user_exists = Permissions.objects.filter(user_id=user).count()
if user_exists:
if perm == None:
## if no permission specified, return all permissions for user ##
return Permissions.objects.filter(user_id=user)
else:
return Permissions.objects.filter(user_id=user).values(perm).last()[perm]
else:
return False
decorator
授权
from django.http import HttpResponseForbidden
from apps.users.models import user_has_perms
## Check if user has permission to load page ##
def authorization_required(permissions=''):
def decorator(view):
def wrapper(request, *args, **kwargs):
can_user = user_has_perms(request.user, permissions)
if can_user or request.user.is_superuser:
return view(request, *args, **kwargs)
else:
return HttpResponseForbidden()
return wrapper
return decorator
views
使用装饰器查看
from decorators.authorization import authorization_required
@login_required
@authorization_required('can_user_view_staff')
def users(request):
user_model = get_user_model()
user_list = user_model.objects.all()
context = {
'users': user_list
}
return render(request, 'users/users.html', context)
context_processor
from apps.users.models import user_has_perms
def permissions(request):
if request.user.is_authenticated:
user_perms = user_has_perms(request.user, None)
else:
user_perms = None
return {
'user_perms': user_perms
}
修改settings.py
添加新处理器
TEMPLATES = [
{
'OPTIONS': {
'context_processors': [
'context_processors.perm_context.permissions',
],
},
},
]
更新 base.html 以在呈现字段之前检查用户权限
{% if user_perms.can_user_view_staff or request.user.is_superuser %}
<a class="dropdown-item" href="/users">User Management</a>
{% endif %}