python运维开发(二十四)----crm权限管理系统
内容目录:
- 数据库设计
- easyUI的使用
数据库设计
权限表Perssion
角色表Role
权限和角色关系表RoleToPermission
用户表UserInfo
用户和角色关系表UserInfoToRole
from django.db import models # Create your models here. class Permission(models.Model): caption = models.CharField(max_length=32) parent_id = models.ForeignKey('Permission', related_name='k', to_field='id', null=True, blank=True) code = models.CharField(max_length=64, null=True,blank=True) method = models.CharField(max_length=16, null=True,blank=True) kwargs = models.CharField(max_length=128, null=True,blank=True) is_menu = models.BooleanField(default=False) def __str__(self): return self.caption class Role(models.Model): name = models.CharField(max_length=32) def __str__(self): return self.name class RoleToPermission(models.Model): menu_id = models.ForeignKey(Permission, to_field='id') role_id = models.ForeignKey(Role, to_field='id') def __str__(self): return "%s-%s" %(self.menu_id.caption, self.role_id.name) # 目标,根据角色列表获取权限 li # 获取当前用户的所有标题权限 # RoleToPermission.objects.filter(role_id__in=li,menu_id__is_menu=True).\ # values('menu_id__caption','menu_id__parent_id','menu_id__parent_id','menu_id__code') # 获取当前用户的所有权限 # RoleToPermission.objects.filter(role_id__in=li).\ # values('menu_id__caption','menu_id__parent_id','menu_id__parent_id','menu_id__code') class UserInfo(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=64) def __str__(self): return self.username class UserInfoToRole(models.Model): user_id = models.ForeignKey(UserInfo, to_field='id') role_id = models.ForeignKey(Role, to_field='id') def __str__(self): return '%s-%s' %(self.user_id.username, self.role_id.name) # userinfo: id = 3 username=alex # result_list = UserInfoToRole.objects.filter(user_id_id=3).values('role_id_id') # UserInfoToRole.objects.filter(user_id_id=1).values_list('role_id_id') # [{'role_id_id': 1}.{'role_id_id': 2}.{'role_id_id': 3}] # 当前用户的角色列表 # li = list(map(lambda x: x['role_id_id'], result_list)) # [1,2,3] # [(1,)] # [1,2,3]
models code
可以通过django自带的后台admin添加插入数据
from django.contrib import admin from app01 import models # Register your models here. admin.site.register(models.Permission) admin.site.register(models.Role) admin.site.register(models.RoleToPermission) admin.site.register(models.UserInfo) admin.site.register(models.UserInfoToRole) # python manage.py createsuperuser # root, root!23456
admin code
创建admin的超级用户root/root!23456
python3 manage.py createsuperuser
上面的models中定义的def __str__只是为了在admin后台中显示正常的名称,否则显示的为对象
easyUI的使用
下载easyui包,引用包中自带的功能
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), url(r'^index/', views.index), url(r'^permission/', views.permission), url(r'^get_permission_tree/', views.get_permission_tree), url(r'^get_child_permission/', views.get_child_permission), url(r'^user/', views.user), ]
Url Code
from django.shortcuts import render, redirect, HttpResponse from app01 import models import json # Create your views here. def login(request): if request.method == 'POST': user = request.POST.get('user') pwd = request.POST.get('pwd') obj = models.UserInfo.objects.filter(username=user, password=pwd).first() if obj: # 当前用户信息保存至Session request.session['user_info'] = {'id': obj.id, 'name': obj.username} # 当前用户角色列表保存至Session result_list = models.UserInfoToRole.objects.filter(user_id_id=obj.id).values('role_id_id') role_list = list(map(lambda x: x['role_id_id'], result_list)) request.session['role_list'] = role_list # 当前用户所有权限加入Session from django.db.models import Count, Min, Max, Sum permission_list = models.RoleToPermission.objects.filter(role_id__in=role_list).values( 'menu_id_id').annotate(c=Count('menu_id_id')).values('menu_id__caption', 'menu_id__parent_id', 'menu_id__code', 'menu_id__method', 'menu_id__kwargs', 'menu_id__id') # 根据permission_id去重 permission_list = list(permission_list) request.session['permission_list'] = permission_list menu_list = models.RoleToPermission.objects.filter(role_id__in=role_list,menu_id__is_menu=True).values( 'menu_id_id').annotate(c=Count('menu_id_id')).values('menu_id__caption', 'menu_id__parent_id', 'menu_id__code', 'menu_id__method', 'menu_id__kwargs', 'menu_id__id',) # 根据permission_id去重 menu_list = list(menu_list) request.session['menu_list'] = menu_list return redirect('/index/') return render(request, 'login.html') def build_node(menu_list, dic): # for menu in menu_list: if menu['id'] == dic['menu_id__parent_id']: temp = {'id': dic['menu_id__id'],'text': dic['menu_id__caption'], 'url': dic['menu_id__code'],'children': []} menu['children'].append(temp) break else: build_node(menu['children'], dic) def build_tree(session_menu_list): # [ {menu_id__parent_id: None, 'menu_id__caption': '权限管理', 'menu_id__code': 'permission'},{},{} ] menu_list = [] # menu_list = [{...}] for dic in session_menu_list: if dic['menu_id__parent_id'] == None: temp = {'id': dic['menu_id__id'],'text': dic['menu_id__caption'], 'url': dic['menu_id__code'],'children': []} menu_list.append(temp) else: # 当前 build_node(menu_list, dic) return menu_list def my_render(request, template_name, context=None, *args, **kwargs): session_menu_list = request.session['menu_list'] menu_list = build_tree(session_menu_list) if context: context['menu_list'] = menu_list else: context = {'menu_list': menu_list} return render(request, template_name, context, *args, **kwargs) def index(request): # 根据session中保存的menu_list生成动态菜单 # session_menu_list = request.session['menu_list'] # menu_list = build_tree(session_menu_list) # # menu_list = [ # { # 'id': 1, # 'text': '权限管理', # 'url': None, # 'children': [ # { # 'id': 4, # 'text': '权限', # 'url': 'permission' # }, # { # 'id': 5, # 'text': '用户', # 'url': 'user' # } # ] # }, # { # 'id': 2, # 'text': '用户管理', # 'url': None # }, # { # 'id': 3, # 'text': '帮助', # 'url': None # } # # # ] return my_render(request, 'index.html') def permission(request): # 当前用户所有的权限 return my_render(request, 'permission.html') def get_permission_tree(request): session_permission_list = request.session['permission_list'] permission_list = build_tree(session_permission_list) return HttpResponse(json.dumps(permission_list)) def get_child_permission(request): node_parent_id = request.GET.get('node_parent_id') page = request.GET.get('page') rows = request.GET.get('rows') page = int(page) rows = int(rows) start = (page - 1) * rows end = page * rows result_queryset = models.Permission.objects.filter(parent_id = node_parent_id).values('caption','code')[start:end] result_list = list(result_queryset) # [ {'caption': 'x', 'code': xxx} ] return HttpResponse(json.dumps(result_list)) def user(request): return my_render(request, 'user.html')
Views Code
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Full Layout - jQuery EasyUI Demo</title> <link rel="stylesheet" type="text/css" href="/static/easyui/themes/default/easyui.css"> <link rel="stylesheet" type="text/css" href="/static/easyui/themes/icon.css"> <script type="text/javascript" src="/static/easyui/jquery.min.js"></script> <script type="text/javascript" src="/static/easyui/jquery.easyui.min.js"></script> <style> .crm-menu{ display: block; padding: 8px; border-bottom: 1px dotted #dddddd; } .crm-menu:hover{ background-color: #E0ECFF; } </style> {% block css %} {% endblock %} </head> <body class="easyui-layout"> <div data-options="region:'north',border:false" style="height:60px;background:#B3DFDA;padding:10px"> LOGO </div> <div data-options="region:'west',split:true,title:'West'" style="width:150px;"> <div id="aa" class="easyui-accordion" style="width:100%;"> {% for menu in menu_list %} <div title="{{ menu.text }}" data-options="iconCls:'icon-ok'" style="overflow:auto;"> {% for child in menu.children %} <a id="menu_{{ child.url }}" href='/{{ child.url }}/' class='crm-menu'>{{ child.text }}</a> {% endfor %} </div> {% endfor %} </div> </div> <div data-options="region:'south',border:false" style="height:50px;background:#A9FACD;padding:10px;">south region</div> <div data-options="region:'center',title:'Center'"> {% block content %} {% endblock %} </div> {% block js %} {% endblock %} </body> </html>
_layout.html
{% extends 'layout/_layout.html' %} {% block content %} <h1>Index</h1> {% endblock %}
Index
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/login/" method="POST"> <input type="text" name="user" /> <input type="password" name="pwd" /> <input type="submit" value="登录" /> </form> </body> </html>
login
{% extends 'layout/_layout.html' %} {% block content %} <div style="float: left;width: 300px"> <ul id="pers_tree" ></ul> <!-- <ul id="tt" class="easyui-tree" data-options="url:'/get_permission_tree/',method:'get',animate:true"></ul> --> </div> <div style="float: left;width: 600px"> <table id="dg"></table> </div> {% endblock %} {% block js %} <script> $(function(){ InitTree(); }); function InitTree(){ $('#pers_tree').tree({ url: '/get_permission_tree/', method: 'get', animate: true, onClick: function(node){ console.log(node.text,node.id); InitTable(node.id); InitPagination(); } }) } function InitTable(node_parent_id){ $('#dg').datagrid({ title: '听不下去了', url: '/get_child_permission/', method: 'get', queryParams: { node_parent_id: node_parent_id }, columns: [[ { field: 'ck', checkbox: true }, { field: 'caption', title: '标题', width: 180, align: 'center' }, { field: 'code', title: 'URL', width: 180, align: 'center' } ]], toolbar: [ { text: '添加', iconCls: 'icon-add', handler: AddRow }, { text: '删除', iconCls: 'icon-remove', handler: RemoveRow }, { text: '修改', iconCls: 'icon-edit', handler: EditRow } ], pagePosition: 'both', pagination: true, pageSize: 10, pageNumber: 1, pageList: [10, 20, 50] }) } function AddRow(){ console.log('addrow'); } function RemoveRow(){ console.log('RemoveRow'); } function EditRow(){ console.log('EditRow'); } function InitPagination() { var pager = $('#dg').datagrid('getPager'); $(pager).pagination({ beforePageText: '第', afterPageText: '页 共{pages}页', displayMsg: '当前显示{from}-{to}条记录 共{total}条数据' }) } </script> {% endblock %}
permission.html
{% extends 'layout/_layout.html' %} {% block content %} <h1>User</h1> {% endblock %} {% block js %} <script> $(function(){ InitMenu(); }); function InitMenu(){ $('#menu_user').addClass('active'); var text = $('#menu_user').parent().prev().find('.panel-title').text(); $('#aa').accordion('select',text); } </script> {% endblock %}
User.html
程序目录结构
python运维开发(二十四)----crm权限管理系统的更多相关文章
- python运维开发(二十二)---JSONP、瀑布流、组合搜索、多级评论、tornado框架简介
内容目录: JSONP应用 瀑布流布局 组合搜索 多级评论 tornado框架简介 JSONP应用 由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. ...
- python运维开发(二十)----models操作、中间件、缓存、信号、分页
内容目录 select Form标签数据库操作 models操作F/Q models多对多表操作 Django中间件 缓存 信号 分页 select Form标签补充 在上一节中我们可以知道Form标 ...
- python运维开发(二十五)---cmdb开发
内容目录: 浅谈ITIL CMDB介绍 Django自定义用户认证 Restful 规范 资产管理功能开发 浅谈ITIL TIL即IT基础架构库(Information Technology Infr ...
- python运维开发常用模块(四)文件对比模块difflib
1.difflib介绍 difflib作为 Python的标准库模块,无需安装,作用是对比文本之间的差异,且支持 输出可读性比较强的HTML文档,与Linux下的diff命令相似.我们可以 使用dif ...
- python运维开发之第四天
一.装饰器 1.器:代表函数,装饰器本质是函数,(装饰器他函数) 2.功能:为其他函数添加附加功能 3.原则: (1)不能修改被装饰函数的源代码 (2)不能修改被装饰函数的调用方式 4.实现装饰器知识 ...
- python运维开发(二十三)---tornado框架
内容目录: 路由系统 模板引擎 cookie 加密cookie 自定义api 自定义session 自定义form表单验证 异步非阻塞 web聊天室实例 路由系统 路由系统其实就是 url 和 类 的 ...
- python运维开发(二十一)----文件上传和验证码+session
内容目录: 文件上传 验证码+session 文件和图片的上传功能 HTML Form表单提交,实例展示 views 代码 HTML ajax提交 原生ajax提交,XMLHttpRequest方式上 ...
- Python运维开发基础09-函数基础【转】
上节作业回顾 #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 实现简单的shell命令sed的替换功能 import ...
- Python运维开发基础08-文件基础【转】
一,文件的其他打开模式 "+"表示可以同时读写某个文件: r+,可读写文件(可读:可写:可追加) w+,写读(不常用) a+,同a(不常用 "U"表示在读取时, ...
随机推荐
- CoreData学习-最好的一片文章
CoreData学习-最好的一片文章 分类: IOS重新上路2014-05-25 18:00 1937人阅读 评论(0) 收藏 举报 目录(?)[+] 写的很好的一篇教程,我什么时候能写出这么 ...
- IOS响应式编程框架ReactiveCocoa(RAC)使用示例-备
ReactiveCocoa是响应式编程(FRP)在IOS中的一个实现框架,它的开源地址为:https://github.com/ReactiveCocoa/ReactiveCocoa# :在网上看了几 ...
- C++之------进制学习
碰到一些寄出的东西不是很理解,就是关于多进制在代码中的转换: 比喻一个数number的多进制表示方法:B:二进制 Q:八进制 D:十进制 H:十六进制 二进制:0bnumber ( ...
- rlwrap 的安装使用
rlwrap 的安装使用 在Windows操作系统上,当在DOS命令窗口中运行SQL*Plus的时候,可以使用向上,向下键来跳回之前已经执行过的SQL语句.你可以根据需要修改他们,然后按Enter键重 ...
- 一些80C51单片机支持双DPTR,C编译器是如何使用它的?
在C51中,C编译器并不利用双DPTR来优化用户所写的程序,只有一些库例程使用了双数据指针.当在两个存储器块之间进行数据复制或比较时,以下库例程会使用双数据指针: memmovememcpymemcm ...
- Hdu2860-Regroup(种类并查集)
Problem Description When ALPC42 got to a panzer brigade, He was asked to build software to help them ...
- Uva227.Puzzle
题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- poj 3262 Protecting the Flowers 贪心
题意:给定n个奶牛,FJ把奶牛i从其位置送回牛棚并回到草坪要花费2*t[i]时间,同时留在草地上的奶牛j每分钟会消耗d[j]个草 求把所有奶牛送回牛棚内,所消耗草的最小值 思路:贪心,假设奶牛a和奶牛 ...
- IO之内核buffer----"buffer cache"
举例 一般情况下,Read,write系统调用并不直接访问磁盘.这两个系统调用仅仅是在用户空间和内核空间的buffer之间传递目标数据. 举个例子,下面的write系统调用仅仅是把3个字节从用户空间拷 ...
- ASP.net ListItem Attributes 属性回传丢失的解决方案
该方法为网上整理 1. 新继承一个列表控件 新控件中重写两个方法: using System; using System.Collections.Generic; using System.Linq; ...