一、内容回顾:
2. django请求生命周期
3. 配置文件
- key必须大写
- 导入配置
from django.conf import settings
3. 在模板中定义函数
- sample_tag
- inclusion_tag
4. 寻找模板的顺序(静态文件)
- 最外层templates目录 (先从static下面找)
- 去注册的app下的templates目录中找(按照app注册顺序)(在从已注册的app下的static下面找)
5. auto示例:所有用户登录后看到的菜单都一样。
二、今日内容
2. 权限组件的应用(含菜单)
3. crm业务
三、内容详细
1. 菜单+权限信息=> 数据库
a. 数据库设计from django.db import models class Menu(models.Model): """ 菜单表 """ title = models.CharField(verbose_name='标题',max_length=32) icon = models.CharField(verbose_name='图标',max_length=32) class Permission(models.Model): """ 权限表 """ url = models.CharField(verbose_name='URL(含正则)', max_length=128) title = models.CharField(verbose_name='名称',max_length=32) name = models.CharField(verbose_name='别名',max_length=32,unique=True) menu = models.ForeignKey(verbose_name='管理菜单',to='Menu',to_field='id',null=True,blank=True) parent = models.ForeignKey(verbose_name='父菜单',to='Permission',null=True,blank=True) class Role(models.Model): """ 角色表 """ title = models.CharField(verbose_name='名称', max_length=32) permissions = models.ManyToManyField(verbose_name='关联权限',to='Permission') class UserInfo(models.Model): """ 用户表 """ username = models.CharField(verbose_name='用户名',max_length=32) password = models.CharField(verbose_name='密码',max_length=64) roles = models.ManyToManyField(verbose_name='关联角色',to='Role')
b. 数据填充
- 去掉web app
- url.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^web/', include('web.urls')),
]
- settings.py
去掉 MENU_LIST
去掉注册的app: 'web.apps.WebConfig',
-新注册app01 python manage.py startapp app01
d. 获取权限和菜单信息
用户登录:test2,UserInfo表中做查询,登录成功后获取两部分数据:
权限 = {
"user": {"url":'/app01/user/'},
"user_add": {"url":'/app01/user/add/'},
"user_edit": {"url":'/app01/user/edit/(d+)'},
"order": {"url":'/app01/order/'},
}
菜单信息 = {
1:{
'title':'用户管理',
'icon':'fa-clipboard',
'children':[
{'title':'用户列表','url':'/app01/user/'},
]
},
2:{
'title':'商品管理',
'icon':'fa-clipboard',
'children':[
{'title':'订单列表','url':'/app01/order/'},
]
}
}
e. 权限控制
1、新建service目录,在目录下新建permission.py文件:用户初始化:将权限信息和菜单信息放入session中
2、在app01下的view.py中,登录函数调用init_permission
f. 动态生成二级菜单
1、在rbac下创建templates目录,放入layout.html母版
2、在templates下创建rbac目录,拷贝文件menu.html
3、在rbac下创建static/rbac目录,在rbac下方面layout.html母版引用的静态文件
4、在app01下创建templates/app01目录,创建user_list.html等页面,引用母版
5、在rbac在创建templatetags,创建rbac文件,动态生成耳机菜单
6、在rbac下新建middlewares,创建rbac.py文件,用户权限校验的中间件
g. 粒度控制到按钮级别
- 权限别名
- filter
@register.filter
def permission(name, request):
if name in request.session.get(settings.RBAC_PERMISSION_SESSION_KEY):
return True
<!-- 在模板中定义filter函数,放在条件语句后面来进行判断,if后为第一个参数,permission后面的request为第二个参数 -->
{% if "user_add"|permission:request %}
<a class="btn btn-primary" href="/app01/user/add/">添加</a>
{% endif %}
2. 使用权限系统
# 创建nb_text app名为url
# 在url中app下models.py中创建数据库,并初始化(1、python manage.py makemigrations/2、python manage.py migrate)
2. 删除rbac/migrations目录中除 __init__.py 以外的所有文件
3. 配置文件中注册 rbac的app
INSTALLED_APPS = [
...
'rbac.apps.RbacConfig',
]
4. 数据库迁移
python manage.py makemigrations
python manage.py migrate
# 在nb_test/urls.py中关联api下的urls.python from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api/', include('api.urls')), ] # 在api在新建urls.py. from django.conf.urls import url, include from django.contrib import admin from api import views urlpatterns = [ url(r'^app/list/', views.app_list, name='app_list'), url(r'^app/list/add/$', views.app_list, name='app_add'), url(r'^app/list/edit/(d+)$/', views.app_list, name='app_edit'), url(r'^app/list/del/(d+)/$', views.app_list, name='app_del'), ] # 在api下的views.py中创建视图函数 from django.shortcuts import render from api import models # Create your views here. def app_list(request): """ 应用列表 :param request: :return: """ app_queryset = models.Application.objects.all() return render(request,'api/app_list.html',{'app_queryset':app_queryset}) # 在api下创建templates/api目录,然后创建app_list.html,继承layout.html母版引用的静态文件
5. 编写测试系统的业务逻辑
<!-- 导入xxxxxxx模块 -->
{% load rbac %}
<!-- 执行get_menu函数并传递了一个参数 -->
{% get_menu request %}
业务逻辑开发完毕....
6. 设置权限相关的配置文件
# ############################ 权限+菜单相关配置 #############################
RBAC_PERMISSION_SESSION_KEY = "ijksdufwesdfs"
RBAC_MENU_SESSION_KEY = "rtwsdfgwerffsd"
'/api/login/',
'/admin/.*'
]
7. 基于django admin 录入权限数据
#python manage.py createsuperuser
#在rbac下的admin.py中写入以下内容
from django.contrib import admin from rbac import models admin.site.register(models.Menu) admin.site.register(models.Permission) admin.site.register(models.Role) admin.site.register(models.UserInfo)
- 权限
- 权限角色关系表
- 角色
- 用户角色关系表
- 用户
8. 权限和菜单信息的应用
- 用户登录:初始化权限和菜单信息
def login(request): """ 用户登录 :param request: :return: """ if request.method == "GET": return render(request, 'api/login.html') user = request.POST.get('user') pwd = request.POST.get('pwd') user = rbac_model.UserInfo.objects.filter(username=user, password=pwd).first() if not user: return render(request, 'api/login.html', {'msg': '用户名或密码错误'}) # ############ 看这里 ############ init_permission(user, request) return redirect('/api/app/list/')
settings.py
MIDDLEWARE = [
...
'rbac.middlewares.rbac.RBACMiddleware',
]
- inclusion_tag:动态生成菜单
layout.html
<div class="menu-body">
{% load rbac %}
</div>
9. 控制页面按钮
{% extends 'layout.html' %} {% load rbac %} {% block content %} <h1>应用列表</h1> {% if 'app_add'|permission:request %} <a class="btn btn-primary" href="{% url 'app_add' %}">添加</a> {% endif %} <table class="table table-bordered"> <thead> <tr> <th>ID</th> <th>姓名</th> {% if "app_edit"|permission:request or "app_del"|permission:request %} <th>操作</th> {% endif %} </tr> </thead> <tbody> {% for row in app_queryset %} <tr> <td>{{ row.id }}</td> <td>{{ row.title }}</td> {% if "app_edit"|permission:request or "app_del"|permission:request %} <td> {% if "app_edit"|permission:request %} <a href="{% url 'app_edit' row.id %}">编辑</a> {% endif %} {% if "app_del"|permission:request %} <a href="{% url 'app_del' row.id %}/">删除</a> {% endif %} </td> {% endif %} </tr> {% endfor %} </tbody> </table> {% endblock %}
四、总结
1. 保存的代码:
- 上一节示例:auto - 7 - 静态的菜单示例(最终版).zip
- 本节示例:nb_test.zip
2. 权限相关
1. 权限系统是如何实现的?
基于角色的权限控制(rbac)
1、用户登录,将用户的权限信息和菜单信息放入session中
2、在中间件中对用户访问的权限进行判断
3、在模板中通过inclusion_tag自动生成二级菜单
2. 权限系统中用了哪些表?表中都有哪些字段?
- 菜单
- 权限
- 权限角色关系表
- 角色
- 用户角色关系表
- 用户
3. 你用中间件实现过什么?为什么使用中间件?
rbac对权限的控制。
因为所有请求都要经过中间件。
4. 你认为哪里最难搞?
- 动态二级菜单+默认选中
- 构建菜单和权限的数据结构时。
5. 其他
...
五、作业
作业:补充 nb_test 应用。
- 8个api操作(使用ModelForm实现增删改查)
url(r'^app/list/$', views.app_list,name='app_list'),
url(r'^app/add/$', views.app_add,name='app_add'),
url(r'^app/edit/(d+)/$', views.app_edit,name='app_edit'),
url(r'^app/del/(d+)/$', views.app_del,name='app_del'),
url(r'^api/list/$', views.api_list,name='api_list'),
url(r'^api/add/$', views.api_add,name='api_add'),
url(r'^api/edit/(d+)/$', views.api_edit,name='api_edit'),
url(r'^api/del/(d+)/$', views.api_del,name='api_del'),
- 9 + api
在api列表中设置一个按钮,点击测试。
"""
pip3 install requests
"""
import requests
response = requests.get(url='http://www.baidu.com')
print(response.status_code)
print(response.text)