rbac、xadmin、django缓存、信号
一、RBAC-基于角色的访问控制
1、概念
# RBAC 是基于角色的访问控制(Role-Based Access Control )
在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便
2、应用
# Django的 Auth组件 采用的认证规则就是RBAC
# 1)像专门做人员权限管理的系统(CRM系统)都是公司内部使用,所以数据量都在10w一下,一般效率要求也不是很高
# 2)用户量极大的常规项目,会分两种用户:前台用户(三大认证) 和 后台用户(BRAC来管理)
# 结论:没有特殊要求的Django项目可以直接采用Auth组件的权限六表,不需要自定义六个表,也不需要断开表关系,单可能需要自定义User表
3、前后台权限控制
# 1)后台用户对各表操作,是后台项目完成的,我们可以直接借助admin后台项目(Django自带的)
# 2)后期也可以用xadmin框架来做后台用户权限管理
# 3)前台用户的权限管理处理:
- 定义了一堆数据接口的视图类,不同的登录用户是否能访问这些视图类,能就代表有权限,不能就代表无权限
- 前台用户权限用drf框架的 三大认证
4、django内置的RBAC(六表)
- 权限三表
![权限三表](https://i-blog.csdnimg.cn/blog_migrate/f3afdf794a127f99c0c3df9055dd4625.png)
- 权限六表
![权限六表](https://i-blog.csdnimg.cn/blog_migrate/2f3fc666d7f71db3f4ca24feb96e9267.png)
- RABC表设计
# 最初三张表
用户表
角色表
权限表
# 六张表:
用户表 角色表 权限表
用户表和角色表是多对多,需要建立第三张表
角色和权限是多对多,需要建立第三张表
用户和权限多对多,建立第三张表
# django内置的rabc六张表:
auth_user:用户表,可扩写
auth_group:角色表(组表)
auth_permission:权限表
auth_user_groups:用户对角色的中间表
auth_group_permissions:角色对权限的中间表
auth_user_user_permissions:用户对权限的中间表
二、xadmin的使用
1、介绍
xadmin是django的第三方扩展,可以让django的admin站点使用更方便
文档:https://xadmin.readthedocs.io/en/latest/index.html
# 安装:
- django 1.x版本的:
pip3 install xadmin
- django 2.x版本的:
pip3 install git+git://github.com/sshwsfc/xadmin.git@django2
或者 pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2
2、使用(django2.x)
- 在app中注册
'rest_framework',
'xadmin',
'crispy_forms',
'reversion',
-修改国际化
# 修改使用中文界面
LANGUAGE_CODE = 'zh-Hans'
# 修改时区
TIME_ZONE = 'Asia/Shanghai'
-建表模型后数据迁移
python3 manage.py makemigrations
python3 manage.py migrate
- 配置路由信息
import xadmin
xversion.autodiscover()
# version模块自动注册需要版本控制的Model
from xadmin.plugins import xversion
xversion.register_models()
urlpatterns = [
path('xadmin/', xadmin.site.urls),
]
- 创建超级用户
python manage.py createsuperuser
- 登录,访问地址,输入用户名密码进入
http://127.0.0.1:8000/xadmin/
3、全局配置和界面美化
-
站点的全局配置
在admin.py中:
import xadmin
from xadmin import views
class BaseSetting(object):
"""xadmin的基本配置"""
enable_themes = True # 开启主题切换功能 (设置成Flase即可关闭)
use_bootswatch = True
xadmin.site.register(views.BaseAdminView, BaseSetting)
class GlobalSettings(object):
"""xadmin的全局配置"""
site_title = "路飞学城" # 设置站点标题
site_footer = "路飞学城有限公司" # 设置站点的页脚
menu_style = "accordion" # 设置菜单折叠
xadmin.site.register(views.CommAdminView, GlobalSettings)
- 站点model管理
# 写一个类
class Bookclass(object):
# 控制该表展示的字段
list_display = ['id', 'name','price','publish','author', ...]
# search_fields 控制可以通过搜索框搜索的字段名称,xadmin使用的是模糊查询
search_fields = ['id', 'name']
# 按照字段过滤
list_filter = ['is_delete']
# 数据导出的可选格式(excel、json、xml格式)
list_export = ('xls', 'xml', 'json') # list_export设置成None来禁用数据导出功能
# ordering 默认排序的字段
# readonly_fields 在编辑页面的只读字段
# exclude 在编辑页面隐藏的字段
# list_editable 在列表页可以快速直接编辑的字段
# show_detail_fields 在列表页提供快速显示详情信息
# refresh_times 指定列表页的定时刷新
refresh_times = [5, 10,30,60] # 设置允许后端管理人员按多长时间(秒)刷新页面
# show_bookmarks 控制是否显示书签功能
show_bookmarks = True
# data_charts 控制显示图表的样式
data_charts = {
"order_amount": {
"title": '图书发布日期表', # 控制图标名称
"x-field": "bpub_date", # 控制x轴字段
"y-field": ('btitle',), # 控制y轴字段
"order": ('id',) # 控制默认排序
},
# 支持生成多个不同的图表
# "order_amount": {
# 'title': '图书发布日期表',
# "x-field": "bpub_date",
# "y-field": ('btitle',),
# "order": ('id',)
# },
}
# 注册:
xadmin.site.register(models.Book, BookClass)
- model_icon控制菜单的图标
class BookAdmin(object):
model_icon = 'fa fa-gift'
# 注册
xadmin.site.rigister(models.Book, BookAdmin)
三、django缓存
1、缓存介绍
在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面.
当一个网站的用户访问量很大的时候,每一次的的后台操作,都会消耗很多的服务端资源,所以必须使用缓存来减轻后端服务器的压力.
缓存是将一些常用的数据保存内存或者memcache中,在一定的时间内有人来访问这些数据时,则不再去执行数据库及渲染等操作,而是直接从内存或memcache的缓存中去取得数据,然后返回给用户.
2、缓存位置
# 1、缓存方式:
- 开发调试缓存
- 内存缓存
- 文件缓存
- 数据库缓存(redis)
- Memcache缓存(使用python-memcached模块)
- Memcache缓存(使用pylibmc模块)
经常使用的有文件缓存和Mencache缓存
# 2、通过配置,设置缓存的位置
- 以文件缓存为例:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', # 指定缓存使用的引擎
'LOCATION': '/var/tmp/django_cache', # 指定缓存的路径
'TIMEOUT': 300, # 缓存超时时间(默认为300秒,None表示永不过期)
'OPTIONS': {
'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
}
}
}
3、缓存粒度
- 整站缓存
- 单页面缓存
- 局部缓存
3.1 单页面缓存(常用)
视图代码示例:
from django.views.decorators.cache import cache_page
@cache_page(5)
def index(request):
import time
ctime = time.time()
return render(request, 'index.html', context = {'ctime':ctime})
3.2 局部缓存
前端代码示例:
# 缓存3秒钟。xxx:唯一key,不能重复
{% load cache %}
{% cache 3 'xxx'%}
这一部分用缓存
时间为:{{ ctime }}
{% endcache %}
3.3 整站缓存(两个中间件)
settings.py中配置中间件:
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware', # 第一,重写了process_response
'...',
'django.middleware.cache.FetchFromCacheMiddleware', # 最后,重写了process_requset
]
# 缓存过期时间设置
CACHE_MIDDLEWARE_SECONDS=5
4、前后端分离后缓存使用
# 1 应用场景:
查出一堆json格式数据,链表查了n个表
# 2 前后端分离以后,只需要会:
-如何把字典,字符串,对象放到缓存中,
-如何取出来
# 3 cache可以缓存所有数据类型,包括自定义的类(内部使用了pickle模块)
# 4 具体使用
from django.core.cache import cache
class BookView(APIView):
def get(self, request):
res_data = cache.get('book_list_dic',)
if res_data: # 有缓存,直接返回数据,不用查数据库
print('走了缓存')
return Response(res_data)
else: # 没有缓存,再查数据库
book_list = models.Book.objects.all()
ser = serializer.BookSer(book_list, many=True)
# 想把ser.data缓存起来
cache.set('book_list_dic', ser.data,100)
print('没走缓存')
return Response(ser.data)
四、django信号
1、django信号介绍
Django提供的一种信号机制。其实就是观察者模式,又称 发布/订阅(Publish/Subscribe)
当发生一些动作的时候,发出信号,然后监听了这个信号的函数就会执行
2、Django内置信号
Model signals:
- pre_init # django的modal执行其构造方法前,自动触发
- post_init # django的modal执行其构造方法后,自动触发
- pre_save # django的modal对象保存前,自动触发
- post_save # django的modal对象保存后,自动触发
- pre_delete # django的modal对象删除前,自动触发
- post_delete # django的modal对象删除后,自动触发
- m2m_changed # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
- class_prepared # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals:
- pre_migrate # 执行migrate命令前,自动触发
- post_migrate # 执行migrate命令后,自动触发
Request/response signals
- request_started # 请求到来前,自动触发
- request_finished # 请求结束后,自动触发
- got_request_exception # 请求异常后,自动触发
Test signals
- setting_changed # 使用test测试修改配置文件时,自动触发
- template_rendered # 使用test测试渲染模板时,自动触发
Database Wrappers
- connection_created # 创建数据库连接时,自动触发
3、内置信号的使用(两种方式)
- 方式一:(函数手动绑定信号)
# 1 导入内置信号
from django.core.signals import request_started
# 2 写一个函数
def aa(sender, **kwargs):
print(sender)
print(kwargs)
print('请求来了,记录一个日志。。。')
# 3 跟内置信号绑定
request_started.connect(aa)
- 方式二:(使用receiver装饰器)
from django.core.signals import request_finished
from django.dispatch import receiver
@receiver(request_finished) # 内置信号pre_save和my_callback函数绑定了
def my_callback(sender, **kwargs):
print("请求走了")
4、信号的应用场景:
- 记录日志(对象创建时就写入日志)
- 解耦合
5、自定义信号
- 定义信号(单独创建一个py文件, 如pizza.py)
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings","size"])
# toppings、size是接受的参数
- 注册信号
def callback(sender, **kwargs):
print('callback')
print(sender, kwargs)
pizza_done.connect(callback)
- 触发信号
from app01.pizza import pizza_done
pizza_done.send(sender='hello', toppings=123, size=456)
# 由于内置信号的触发者已经集成到django中,所以其会自动调用,而对于自定义的信号则需要开发者在任意位置触发