权限说明
场景:不同的用户具有不同的权限,如只有vip用户可以享受高速下载服务,只有svip用户才可以享受极速下载服务。
思路:为用户添加角色,通过为角色添加权限从而达到权限控制的目的。之所以通过角色来控制权限是为了后期良好的扩展性,可能vip用户和svip用户都具有查看某电影的权限,同时具有下载权限,但是svip具有高速下载权限,后期如果权限变动更容易拓展维护。
数据表设计
代码实现
model模型类:
from datetime import datetime
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserProfile(AbstractUser):
nick_name = models.CharField(max_length=50, verbose_name="昵称", default="")
birthday = models.DateField(verbose_name="生日", null=True, blank=True)
gender = models.CharField(verbose_name="性别", choices=GENDER_CHOICES, max_length=6)
address = models.CharField(max_length=100, verbose_name="地址", default="")
mobile = models.CharField(max_length=11, verbose_name="手机号码")
image = models.ImageField(verbose_name="用户头像", upload_to="head_image/%Y/%m", default="default.jpg")
class Meta:
verbose_name = "用户信息"
verbose_name_plural = verbose_name
def unread_nums(self):
# 未读消息数量
return self.usermessage_set.filter(has_read=False).count()
def __str__(self):
if self.nick_name:
return self.nick_name
else:
return self.username
class Role(models.Model):
role = models.CharField(max_length=50, verbose_name='角色')
role_description = models.CharField(max_length=50, verbose_name='角色描述')
user = models.ManyToManyField(to=UserProfile, blank=True, verbose_name='关联用户')
class Meta:
verbose_name = "角色信息"
verbose_name_plural = verbose_name
class Permission(models.Model):
permission = models.CharField(max_length=50, verbose_name='权限')
per_description = models.CharField(max_length=50, verbose_name='权限描述')
role = models.ManyToManyField(to=Role, blank=True, verbose_name='关联角色')
class Meta:
verbose_name = "权限信息"
verbose_name_plural = verbose_name
权限验证装饰器:
from django.http import JsonResponse
def permission_verify(request, permission=None):
"""
权限验证装饰器
:param request:
:param permission:
:return:
"""
def per_verify(func):
def wrapper(request, *args, **kwargs):
user = request.user
# 获取当前用户所有权限
roles = user.user_role_set.all()
per_set = set()
for role in roles:
pers = role.role_per_set.all()
for per in pers:
per_set.add(per.permission)
per_list = list(per_set)
if 'admin' in per_list:
return func(*args, **kwargs)
elif permission in per_list:
return func(*args, **kwargs)
else:
data = {'status': 'fail', 'message': '无权限'}
return JsonResponse(data)
return wrapper
return per_verify
视图中验证
from apps.utils.user_util import permission_verify
from django.utils.decorators import method_decorator
class MyMessageView(LoginRequiredMixin, View):
'''
我的消息
'''
login_url = "/login/"
# 进行权限验证
@method_decorator(permission_verify(permission='admin'))
def get(self, request, *args, **kwargs):
messages = UserMessage.objects.filter(user=request.user)
current_page = "message"
for message in messages:
message.has_read = True
message.save()
# 对消息数据进行分页
try:
page = request.GET.get('page', 1)
except PageNotAnInteger:
page = 1
p = Paginator(messages, per_page=1, request=request)
messages = p.page(page)
return render(request, "usercenter-message.html",{
"messages":messages,
"current_page":current_page
})
通过admin后台对role和permission表进行操作即可进行相应的角色和权限管理。