django项目(CRM项目继续,做到权限粒度划分到按钮)

内容回顾:

1.使用别人源码,启动:解释器+工作目录

2. django请求生命周期

3. 配置文件
- key必须大写
- 导入配置
from django.conf import settings

3. 在模板中定义函数
- sample_tag
- inclusion_tag

4. 寻找模板的顺序(静态文件)
- 最外层templates目录 (static)
- 去注册的app下的templates目录中找(按照app注册顺序)(static)

5. auto示例:所有用户登录后看到的菜单都一样。


今日内容:
1. 菜单+权限信息=> 数据库

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. 数据填充


c. 上一节功能去掉
- 去掉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',


d. 获取权限和菜单信息
用户登录:马帅,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. 权限控制


f. 动态生成二级菜单



g. 粒度控制到按钮级别
- 权限别名
- filter


2. 使用权限系统
1. 拷贝rbac应用

2. 删除rbac/migrations目录中除 __init__.py 以外的所有文件

3. 配置文件中注册 rbac的app
INSTALLED_APPS = [
...
'rbac.apps.RbacConfig',
]

4. 数据库迁移
python manage.py makemigrations
python manage.py migrate


5. 编写测试系统的业务逻辑
如果使用rbac中的模板的话,需要先删除layout.html中的:
<!-- 导入xxxxxxx模块 -->
{% load rbac %}
<!-- 执行get_menu函数并传递了一个参数 -->
{% get_menu request %}

业务逻辑开发完毕....

6. 设置权限相关的配置文件
# ############################ 权限+菜单相关配置 #############################
RBAC_PERMISSION_SESSION_KEY = "ijksdufwesdfs"
RBAC_MENU_SESSION_KEY = "rtwsdfgwerffsd"

VALID_LIST = [
'/api/login/',
'/admin/.*'
]

7. 基于django admin 录入权限数据
- 菜单
- 权限
- 权限角色关系表
- 角色
- 用户角色关系表
- 用户

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 %}

{% get_menu request %}
</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)

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)



总结:
1、layout.html在外层,项目会先找外层的,外层没有会按照app的注册顺序找里层的。

 

posted @ 2018-10-22 23:44  信、达、雅  阅读(468)  评论(0编辑  收藏  举报