这里写目录标题
- 一、权限的数据的特点
- 二、首先settings.py文件中配置redis
- 连接redis数据库
一、权限的数据的特点
需要去数据库中频繁的读和写,为了项目提高运行效率,可以把用户的权限在每次登录的时候都缓存到redis中。这样的话,权限判断的中间件就可以方便的从redis中得到当前用户的所有权限,从而判断。
对于那些数据量大,并且需要频繁的读写,一定需要做缓存的
在默认的app中定义utils包,创建cache_permissions.py
二、首先settings.py文件中配置redis
# 配置Redis数据库
CACHES = {
"default": { # 默认
"BACKEND": "django_redis.cache.RedisCache",
#"LOCATION": "redis://82.156.178.247:6379/0",
"LOCATION": "redis://127.0.0.1:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
"session": { # session
"BACKEND": "django_redis.cache.RedisCache",
# "LOCATION": "redis://82.156.178.247:6379/1",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
"verify_code": { # 验证码
"BACKEND": "django_redis.cache.RedisCache",
# "LOCATION": "redis://82.156.178.247:6379/2",
"LOCATION": "redis://127.0.0.1:6379/2",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"
连接redis数据库
首先安装django-redis
pip install django-reids
获得redis数据库的连接
from django_redis import get_redis_connection
redis_conn=get_redis_connection(“default”)
以哈希的方式,存储数据到redis中
redis_conn.hmset(f’user.id’,permissions_dict)
把当前用户的权限信息,缓存到redis数据库中
redis中存放用户权限的结构为:user_用户id——>字典{key:path,value[列表]}——》json字符串
from erp_system.models import MenuModel,PermissionsModel
import json
from django_redis import get_redis_connection
def redis_storage_permissions(user):
"""
把当前用户的权限信息,缓存到redis数据库中
redis中存放用户权限的结构为:user_用户id——>字典{key:path,value[列表]}——》json字符串
"""
#查询当前登录用户,拥有的权限id列表,values_list: 返回列表中套元组,values:返回列表中套字典
permission_ids = user.roles.values_list('permissions', flat=True).distinct()
#根据权限id,获取权限的所有值,一级菜单的权限除外
permissions=PermissionsModel.objects.filter(is_menu=False,id__in=permission_ids).values('id','path','method','name')
#permissions是查询集,嵌套字典的列表
if not permissions.exists(): #没有查询到权限
return
permissions_dict={} #todo 存放当前用户的权限,path为key
for permission in permissions:
#因为数据需要转换成json格式的字符串,所以排除那些特殊符号
#'\u200b'是Unicode中的零度字符,可以理解为不可见字符,例如回车、换行符、制表符
method=str(permission.get('method')).replace('\u200b','')
path=str(permission.get('path')).replace('\u200b','')
_name=str(permission.get('name')).replace('\u200b','')
_id=permission.get('id')
if path in permissions_dict:
permissions_dict[path].append({ #todo 一个请求路径有很多的权限(增删改查),只是method不同
'method':method,
'sign':_name,
'id':_id
})
else:
permissions_dict[path]=[{ #如果没有path,添加进去
'method': method,
'sign': _name,
'id': _id
}]
for key in permissions_dict:
permissions_dict[key]=json.dumps(permissions_dict[key])
print(permissions_dict)
#todo 存放到redis中
redis_conn=get_redis_connection("default") #todo 获得redis数据库的连接
redis_conn.hmset(f'user_{user.id}',permissions_dict) # todo 以哈希的方式,存放数据到redis
用户认证通过后,自动调用redis_storage_permissions(user)方法
from django.contrib.auth.backends import ModelBackend
from .models import UserModel
import logging
from erp_project.utils.cache_permissions import redis_storage_permissions
logger = logging.getLogger('erp')
class UserLoginAuth(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
"""
实现用户认证
"""
try:
user = UserModel.objects.get(username=username)
logger.info(user)
except:
return None
#判断密码
if user.check_password(password):
redis_storage_permissions(user) #todo 调用缓存数据的方法
return user # 把user对象放到request对象中
登录操作后,查看缓存中的数据