西游之路——python全栈——报障系统之后台管理
Posted 陆游憩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了西游之路——python全栈——报障系统之后台管理相关的知识,希望对你有一定的参考价值。
一、后台管理页面布局
1、用户:
- 普通用户
知识库+提交报账单+个人信息
- 管理员
知识库+提交报账单+个人信息+处理报账单
- 超级管理员
知识库+提交报账单+个人信息+处理报账单+报障统计信息
权限管理
2、菜单:
- 知识库管理
文章
标签
分类
- 报障管理
个人报障
报障处理
报障统计信息
- 权限管理
菜单
权限
角色
二、公共模板及路由分发
1、后台菜单栏、导航栏
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>{% block title %}{% endblock %}</title> 6 <link rel="stylesheet" href="/static/css/commons.css"> 7 <style> 8 body{ 9 margin: 0; 10 } 11 .pg-header{ 12 height: 48px; 13 background-color: #79aec8; 14 line-height: 48px; {# 上下居中 #} 15 min-width: 1000px; 16 } 17 .pg-header .logo{ 18 color: white; 19 font-size: 24px; 20 width: 250px; 21 background-color: #417690; 22 text-align: center; 23 } 24 .pg-header .h1-menu .item, .pg-header .hr-menu .item{ 25 padding:0 15px; 26 color: white; 27 height: 48px; 28 display: inline-block; 29 } 30 .pg-header .h1-menu .item:hover, .pg-header .hr-menu .item:hover{ 31 background-color: #417690; 32 } 33 .pg-header .h1-menu .item-set{ 34 display: inline-block; 35 position: relative; 36 } 37 .pg-header .h1-menu .item-set .sets{ 38 position: absolute; 39 background-color: aliceblue; 40 border: 1px solid #dddddd; {# 边框 #} 41 width: 150px; 42 color: white; 43 display: none; 44 } 45 .pg-header .h1-menu .item-set .sets a{ 46 display: block; 47 line-height: 30px; 48 } 49 .pg-header .h1-menu .item-set:hover .sets{ 50 display: block; 51 } 52 .left{ 53 float: left; 54 } 55 .right{ 56 float: right; 57 } 58 .hide{ 59 display: none; 60 } 61 .avatar{ 62 display: inline-block; 63 position: relative; 64 } 65 .avatar img{ 66 height: 30px; 67 border-radius: 50%; 68 } 69 .avatar .sets{ 70 width: 150px; 71 position: absolute; 72 background-color: aliceblue; 73 border: 1px solid #dddddd; 74 color: white; 75 left: -128px; 76 display: none; 77 top: 48px; 78 } 79 .avatar .sets a{ 80 display: block; 81 line-height: 30px; 82 } 83 .avatar:hover .sets{ 84 display: block; 85 } 86 .pg-body .menus{ 87 width: 250px; 88 position: absolute; 89 top: 48px; 90 left: 0; 91 bottom: 0; 92 background-color: #79aec8; 93 } 94 .pg-body .contents{ 95 position: absolute; 96 top: 48px; 97 right: 0; 98 bottom: 0; 99 left: 260px; 100 overflow: scroll; 101 } 102 .menus{ 103 text-align: center; 104 } 105 .menus .item .item-title{ 106 background-color: #dddddd; 107 border-right: 3px solid transparent; 108 } 109 .menus .item a{ 110 color: white; 111 display: block; 112 padding: 5px 8px; 113 font-size: 16px; 114 } 115 .menus .item .item-content a{ 116 display: block; 117 padding: 5px 8px; 118 border-right: 3px solid transparent; 119 } 120 .menus .item .item-content a:hover{ 121 border-right: 3px solid green; 122 } 123 {# 块级标签空格隔开, a.active不隔开#} 124 .menus .item .item-content a.active{ 125 border-right: 3px solid green; 126 } 127 .menus .item .item-title:hover{ 128 border-right: 3px solid green; 129 } 130 </style> 131 {% block css %}{% endblock %} 132 </head> 133 <body> 134 <div class="pg-header"> 135 <div class="logo left">陆军请发言</div> 136 <div class="h1-menu left"> 137 <a class="item" href="#">博客首页</a> 138 </div> 139 <div class="hr-menu right"> 140 <a class="item" href="#">消息 141 <i class="fa fa-bell-o" aria-hidden="true"></i> 142 </a> 143 <a class="item" href="#">通知 144 <i class="fa fa-envelope-o" aria-hidden="true"></i> 145 </a> 146 <a class="item" href="#">消息 147 <i class="fa fa-commenting-o" aria-hidden="true"></i> 148 </a> 149 <div class="avatar right"> 150 <a class="item" href="#"> 151 <img src="/static/7.jpg"> 152 </a> 153 <div class="sets"> 154 <a href="#">菜单四-1</a> 155 <a href="#">菜单四-2</a> 156 <a href="#">菜单四-3</a> 157 </div> 158 </div> 159 </div> 160 </div> 161 <div class="pg-body"> 162 <div class="menus"> 163 <div class="item"> 164 <a href="/backend/article-0-0.html"> 165 <i class="fa fa-cogs" aria-hidden="true"></i> 166 文章管理 167 </a> 168 </div> 169 <div class="item"> 170 <a href="/backend/tag-0-0.html"> 171 <i class="fa fa-cogs" aria-hidden="true"></i> 172 标签管理 173 </a> 174 </div> 175 <div class="item"> 176 <a href="/backend/category-0-0.html"> 177 <i class="fa fa-cogs" aria-hidden="true"></i> 178 分类管理 179 </a> 180 </div> 181 <div class="item"> 182 <a href="/backend/trouble_list.html"> 183 <i class="fa fa-cogs" aria-hidden="true"></i> 184 报障管理 185 </a> 186 </div> 187 </div> 188 <div class="contents"> 189 {% block content %}{% endblock %} 190 </div> 191 </div> 192 <div class="pg-footer"></div> 193 194 <script src="/static/js/jquery.js"></script> 195 <script> 196 197 function Title1() { 198 $(‘#menu_tag‘).parent().removeClass(‘hide‘); 199 } 200 function Title2() { 201 $(‘#menu_article‘).parent().removeClass(‘hide‘); 202 } 203 function Title3() { 204 $(‘#menu_category‘).parent().removeClass(‘hide‘); 205 } 206 207 </script> 208 {% block js %}{% endblock %} 209 </body> 210 </html>
2、画图——带标识的曲线图
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <link rel="icon" href="https://static.jianshukeji.com/highcharts/images/favicon.ico"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <style> 8 /* css 代码 */ 9 10 </style> 11 <script src="https://img.hcharts.cn/highcharts/highcharts.js"></script> 12 <script src="https://img.hcharts.cn/highcharts/modules/exporting.js"></script> 13 <script src="https://img.hcharts.cn/highcharts-plugins/highcharts-zh_CN.js"></script> 14 <script src="/static/JS/jquery.js"></script> 15 </head> 16 <body> 17 <div id="container" style="min-width:400px;height:400px"></div> 18 <script> 19 $(function () { 20 initChart(); 21 }); 22 function initChart() { 23 var config = { 24 chart: { 25 type: ‘spline‘ 26 }, 27 title: { 28 text: ‘两地月平均温度‘ 29 }, 30 subtitle: { 31 text: ‘数据来源: WorldClimate.com‘ 32 }, 33 xAxis: { 34 title: { 35 text: ‘时间‘ 36 }, 37 labels: { 38 formatter: function () { 39 return this.value; 40 } 41 } 42 }, 43 yAxis: { 44 title: { 45 text: ‘个数‘ 46 }, 47 labels: { 48 formatter: function () { 49 return this.value + ‘个‘; 50 } 51 } 52 }, 53 tooltip: { 54 crosshairs: true, 55 shared: true 56 }, 57 legend: { 58 enabled: true 59 }, 60 plotOptions: { 61 spline: { 62 marker: { 63 radius: 4, 64 lineColor: ‘#666666‘, 65 lineWidth: 1 66 } 67 } 68 }, 69 exporting: { 70 enabled: false 71 }, 72 series: [ 73 { 74 name: ‘东京‘, 75 marker: { 76 symbol: ‘square‘ 77 }, 78 data: [ 79 [0, 15], 80 [10, -50], 81 [20, -56.5], 82 [30, -46.5] 83 ] 84 }, 85 { 86 name: ‘伦敦‘, 87 marker: { 88 symbol: ‘diamond‘ 89 }, 90 data: [ 91 [0, 15], 92 [5, -50], 93 [20, -56.5], 94 [30, -46.5] 95 ] 96 } 97 ] 98 } 99 100 //数据库中获取series 101 $.ajax({ 102 url: ‘/backend/trouble_report.html‘, 103 dataType: ‘json‘, 104 success: function(arg) { 105 config[‘series‘] = arg; 106 Highcharts.chart(‘container‘,config); 107 } 108 }); 109 } 110 111 </script> 112 </body> 113 </html>
3、路由分发
1 urlpatterns = [ 2 re_path(‘^admin/‘, admin.site.urls), 3 re_path(‘^backend/‘, include(‘backend.urls‘)), 4 re_path(‘^‘, include(‘web.urls‘)), 5 ]
三、后台首页
url路由
1 re_path(‘^index.html$‘, user.index),
视图函数
View Code
模块
backend_index.html
四、文章管理
url路由
1 re_path(‘^add_article.html$‘, user.add_article), 2 re_path(‘^edit_article-(d+).html$‘, user.edit_article), 3 re_path(‘^article-(?P<tags_id>(d+))-(?P<category_id>(d+)).html$‘, user.article, name=‘article‘),
视图函数
1 def article(request,*args,**kwargs): 2 current_page = request.GET.get(‘p‘) 3 # 构造字典condition,并除去零,condition用于判断 4 condition = {} 5 for k,v in kwargs.items(): 6 tem = int(v) 7 kwargs[k] = tem 8 if tem: 9 condition[k] = tem 10 if condition: 11 article_list = models.Article.objects.filter(**condition).all() 12 current_url = reverse(‘article‘, kwargs=kwargs) 13 else: 14 current_url = ‘/backend/article-0-0.html‘ ####### 15 article_list = models.Article.objects.all() 16 print(article_list.count()) 17 obj_list = Pagination(article_list.count(), current_page, current_url) 18 data_list = article_list[obj_list.start():obj_list.end()] 19 data_count = article_list.count() 20 21 tag_list = models.Tags.objects.all() 22 category_list = models.Category.objects.all() 23 24 return render(request, ‘backend_article.html‘,{ 25 ‘tag_list‘:tag_list, 26 ‘category_list‘:category_list, 27 ‘kwargs‘:kwargs, 28 ‘data_list‘:data_list, 29 ‘obj_list‘:obj_list, 30 ‘data_count‘:data_count, 31 }) 32 33 def edit_article(request,nid): 34 if request.method == ‘GET‘: 35 data = models.Article.objects.filter(id=nid).first() 36 obj = ArticleForm(initial={ 37 ‘title‘:data.title, 38 ‘summary‘:data.summary, 39 ‘detail‘:data.detail, 40 ‘user‘:data.user_id, 41 ‘blog‘:data.blog_id, 42 ‘tags‘:data.tags_id, 43 ‘category‘:data.category_id, 44 }) 45 return render(request, ‘backend_edit_article.html‘,{ 46 ‘obj‘:obj, 47 ‘nid‘:nid 48 }) 49 else: 50 obj = ArticleForm(request.POST) 51 if obj.is_valid(): 52 models.Article.objects.filter(id=nid).update(**obj.cleaned_data) 53 return redirect(‘/backend/article-0-0.html‘) 54 else: 55 return render(request, ‘backend_edit_article.html‘, { 56 ‘obj‘: obj, 57 ‘nid‘: nid 58 }) 59 60 def add_article(request): 61 if request.method == ‘GET‘: 62 obj = ArticleForm() 63 return render(request,‘backend_add_article.html‘,{‘obj‘:obj}) 64 else: 65 obj = ArticleForm(request.POST) 66 if obj.is_valid(): 67 print(obj.cleaned_data) 68 models.Article.objects.create(**obj.cleaned_data) 69 return redirect(‘/backend/article-0-0.html‘) 70 else: 71 return render(request, ‘backend_add_article.html‘, { 72 ‘obj‘: obj 73 })
模块
1 {% extends ‘backend_layout.html‘ %} 2 3 {% block css %} 4 <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> 5 <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> 6 <style> 7 .condition a{ 8 display: inline-block; 9 padding: 5px 8px; 10 border: 1px solid #dddddd; 11 } 12 .condition a.active{ 13 background-color: coral; 14 } 15 .menu{ 16 height: 48px; 17 background-color: #dddddd; 18 line-height: 48px; 19 } 20 .menu a{ 21 padding: 5px; 22 } 23 .tool{ 24 height: 40px; 25 background-color: #dddddd; 26 line-height: 40px; 27 } 28 .tool .num{ 29 padding: 0 8px; 30 } 31 .tool .add{ 32 background-color: #79aec8; 33 width: 200px; 34 text-align: center; 35 } 36 .tool .add a{ 37 color: white; 38 } 39 </style> 40 {% endblock %} 41 42 {% block content %} 43 <div class="menu"> 44 <a href="#">文章管理</a> 45 | 46 文章列表 47 </div> 48 <hr> 49 <i class="fa fa-search" aria-hidden="true"></i> 50 <input type="text" placeholder="搜索条件"> 51 <hr> 52 <div class="condition"> 53 <div> 54 {# 高亮显示选中 #} 55 {% if kwargs.tags_id == 0 %} 56 <a class="active" href="/backend/article-0-{{kwargs.category_id}}.html">全部</a> 57 {% else %} 58 <a href="/backend/article-0-{{kwargs.category_id}}.html">全部</a> 59 {% endif %} 60 {% for item in tag_list %} 61 {% if item.id == kwargs.tags_id %} 62 <a class="active" href="/backend/article-{{item.id}}-{{kwargs.category_id}}.html">{{item.caption}}</a> 63 {% else %} 64 <a href="/backend/article-{{item.id}}-{{kwargs.category_id}}.html">{{item.caption}}</a> 65 {% endif %} 66 {% endfor %} 67 </div> 68 <div> 69 {% if kwargs.category_id == 0 %} 70 <a class="active" href="/backend/article-{{kwargs.tags_id}}-0.html">全部</a> 71 {% else %} 72 <a href="/backend/article-{{kwargs.tags_id}}-0.html">全部</a> 73 {% endif %} 74 {% for item in category_list %} 75 {% if item.id == kwargs.category_id %} 76 <a class="active" href="/backend/article-{{kwargs.tags_id}}-{{item.id}}.html">{{item.caption}}</a> 77 {% else %} 78 <a href="/backend/article-{{kwargs.tags_id}}-{{item.id}}.html">{{item.caption}}</a> 79 {% endif %} 80 {% endfor %} 81 </div> 82 </div> 83 <hr> 84 <div class="tool"> 85 <div class="num left"> 86 <i class="fa fa-calendar" aria-hidden="true"></i> 87 搜索文章({{data_count}}篇) 88 </div> 89 <div class="add right"> 90 <a href="/backend/add_article.html"> 91 <i class="fa fa-plus-circle" aria-hidden="true"></i> 92 创建新文章 93 </a> 94 </div> 95 </div> 96 <hr> 97 <div class="container"> 98 <div> 99 <table class="table table-bordered table-striped"> 100 <thead> 101 <tr> 102 <th>文章标题</th> 103 <th>操作</th> 104 </tr> 105 </thead> 106 <tbody id="tb"> 107 {% for row in data_list %} 108 <tr nid="{{row.id}}"> 109 <td na="article">{{row.title}}</td> 110 <td> 111 <button type="button" class="btn btn-danger"> 112 <i class="fa fa-times" aria-hidden="true"></i> 113 删除 114 </button> 115 | 116 <a href="/backend/edit_article-{{row.id}}.html" type="button" class="btn btn-primary"> 117 <i class="fa fa-pencil-square-o" aria-hidden="true"></i> 118 编辑 119 </a> 120 </td> 121 </tr> 122 {% endfor %} 123 </tbody> 124 </table> 125 </div> 126 </div> 127 <hr> 128 <div class="right"> 129 <nav aria-label="Page navigation"> 130 <ul class="pagination"> 131 {{obj_list.page_str|safe}} 132 </ul> 133 </nav> 134 </div> 135 136 {% endblock %}
===================
1 {% extends ‘backend_layout.html‘ %} 2 3 {% block css %} 4 <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> 5 <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> 6 <link rel="stylesheet" href="/static/plugins/kindeditor/themes/default/default.css"> 7 <style> 8 .kind-content{ 9 width: 100%; 10 min-height: 500px; 11 } 12 </style> 13 {% endblock %} 14 15 {% block content %} 16 17 <form action="/backend/add_article.html" method="POST" enctype="multipart/form-data" novalidate> 18 {% csrf_token %} 19 <ul> 20 <li>{{obj.title.label}}{{obj.title}}{{obj.errors.title.0}}</li> 21 <li>{{obj.summary.label}}{{obj.summary}}{{obj.errors.summary.0}}</li> 22 <li>{{obj.detail.label}}{{obj.detail}}{{obj.errors.detail.0}}</li> 23 <li>{{obj.user.label}}{{obj.user}}{{obj.errors.user.0}}</li> 24 <li>{{obj.blog.label}}{{obj.blog}}{{obj.errors.blog.0}}</li> 25 <li>{{obj.tags.label}}{{obj.tags}}{{obj.errors.tags.0}}</li> 26 <li>{{obj.category.label}}{{obj.category}}{{obj.errors.category.0}}</li> 27 </ul> 28 <input type="submit" value="提交"> 29 </form> 30 {% endblock %} 31 32 {% block js %} 33 34 <script charset="utf-8" src="/static/plugins/kindeditor/kindeditor-all.js"></script> 35 <script charset="utf-8" src="/static/plugins/kindeditor/lang/zh_CN.js"></script> 36 <script> 37 KindEditor.ready(function (K) { 38 var editor = K.create(‘#detail‘,{ 39 resizeType: 1 40 }) 41 }); 42 </script> 43 {% endblock %}
===================
1 {% extends ‘backend_layout.html‘ %} 2 3 {% block css %} 4 <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> 5 <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> 6 <link rel="stylesheet" href="/static/plugins/kindeditor/themes/default/default.css"> 7 <style> 8 .kind-content{ 9 width: 100%; 10 min-height: 500px; 11 } 12 </style> 13 {% endblock %} 14 15 {% block content %} 16 17 <form action="/backend/edit_article-{{nid}}.html" method="POST" enctype="multipart/form-data" novalidate> 18 {% csrf_token %} 19 <ul> 20 <li>{{obj.title.label}}{{obj.title}}{{obj.errors.title.0}}</li> 21 <li>{{obj.summary.label}}{{obj.summary}}{{obj.errors.summary.0}}</li> 22 <li>{{obj.detail.label}}{{obj.detail}}{{obj.errors.detail.0}}</li> 23 <li>{{obj.user.label}}{{obj.user}}{{obj.errors.user.0}}</li> 24 <li>{{obj.blog.label}}{{obj.blog}}{{obj.errors.blog.0}}</li> 25 <li>{{obj.tags.label}}{{obj.tags}}{{obj.errors.tags.0}}</li> 26 <li>{{obj.category.label}}{{obj.category}}{{obj.errors.category.0}}</li> 27 </ul> 28 <input type="submit" value="提交"> 29 </form> 30 {% endblock %} 31 32 33 {% block js %} 34 35 <script charset="utf-8" src="/static/plugins/kindeditor/kindeditor-all.js"></script> 36 <script charset="utf-8" src="/static/plugins/kindeditor/lang/zh_CN.js"></script> 37 <script> 38 KindEditor.ready(function (K) { 39 var editor = K.create(‘#detail‘,{ 40 resizeType: 1 41 }) 42 }); 43 </script> 44 {% endblock %}
五、报障管理
普通用户
- 报障列表
- 创建报障单
- 修改(未处理)
- 查看解决方案
- 评分(已处理)
管理员
- 报障列表(自己 或 未处理)
- 处理报账单
老板
- all
六、报障管理coding实例
1、普通用户
models数据库
warning.py
url路由
1 # 一般用户:提交报账单,查看,修改(未处理),评分(已处理,未评论) 2 re_path(‘^trouble_list.html$‘, trouble.trouble_list), 3 re_path(‘^add_trouble.html$‘, trouble.add_trouble), 4 re_path(‘^edit_trouble-(d+).html$‘, trouble.edit_trouble),
视图函数
1 from django.shortcuts import render,redirect,HttpResponse 2 from repository import models 3 from utils.pager import Pagination 4 from utils.form import TroubleForm 5 6 def trouble_list(request): 7 # current_user_id = request.session.get(‘user_info_id‘) 8 current_user_id = 1 9 trouble_list = models.Warning.objects.filter(submit_id=current_user_id).order_by(‘status‘).only(‘title‘,‘status‘,‘create_date‘,‘processor‘) 10 data_count = trouble_list.count() 11 12 current_page = request.GET.get(‘p‘) 13 current_url = ‘/backend/trouble_list.html‘ 14 obj_list = Pagination(trouble_list.count(), current_page, current_url) 15 data_list = trouble_list[obj_list.start():obj_list.end()] 16 return render(request, ‘backend_trouble_list.html‘,{ 17 ‘data_count‘:data_count, 18 ‘data_list‘:data_list, 19 ‘obj_list‘:obj_list, 20 }) 21 22 import datetime 23 def add_trouble(request): 24 if request.method == ‘GET‘: 25 form = TroubleForm() 26 return render(request, ‘backend_add_trouble.html‘,{ 27 ‘form‘:form, 28 }) 29 else: 30 form = TroubleForm(request.POST) 31 if form.is_valid(): 32 # 不需要验证的不用写入form,可以直接取 33 dic = {} 34 dic[‘submit_id‘] = 1 # session中取 35 dic[‘create_date‘] = datetime.datetime.now() 36 dic[‘status‘] = 1 37 dic.update(form.cleaned_data) # 把字典form.cleaned_data加入dic 38 models.Warning.objects.create(**dic) 39 return redirect(‘/backend/trouble_list.html‘) 40 else: 41 return render(request, ‘backend_add_trouble.html‘, { 42 ‘form‘: form, 43 }) 44 45 def edit_trouble(request,nid): 46 if request.method == ‘GET‘: 47 obj = models.Warning.objects.filter(id=nid,status=1).only(‘id‘,‘title‘,‘detail‘).first() 48 if not obj: 49 return HttpResponse(‘处理中的单无法编辑‘) 50 # 当所传字典有空值时,initial不会触发error报错,data会触发 51 form = TroubleForm(initial={‘title‘:obj.title, ‘detail‘:obj.detail}) 52 return render(request, ‘backend_edit_trouble.html‘,{‘form‘:form, ‘nid‘:nid}) 53 else: 54 form = TroubleForm(request.POST) 55 if form.is_valid(): 56 # update时,v为受影响的行数 57 # create时,v为对象 58 v = models.Warning.objects.filter(id=nid,status=1).update(**form.cleaned_data) 59 if not v: 60 return HttpResponse(‘已经被处理‘) 61 return redirect(‘/backend/trouble_list.html‘) 62 else: 63 return render(request, ‘backend_edit_trouble.html‘, {‘form‘: form, ‘nid‘:nid})
模块
1 {% extends ‘backend_layout.html‘ %} 2 3 {% block css %} 4 <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> 5 <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> 6 <style> 7 .menu{ 8 height: 48px; 9 background-color: #dddddd; 10 line-height: 48px; 11 } 12 .menu a{ 13 padding: 5px; 14 } 15 .tool{ 16 height: 40px; 17 background-color: #dddddd; 18 line-height: 40px; 19 } 20 .tool .num{ 21 padding: 0 8px; 22 } 23 .tool .add{ 24 background-color: #79aec8; 25 width: 200px; 26 text-align: center; 27 } 28 .tool .add a{ 29 color: white; 30 } 31 </style> 32 {% endblock %} 33 34 {% block content %} 35 <div class="menu"> 36 <a href="#">报障管理</a> 37 | 38 报障列表 39 </div> 40 <hr> 41 <i class="fa fa-search" aria-hidden="true"></i> 42 <input type="text" placeholder="搜索条件"> 43 <hr> 44 <a href="/backend/trouble_kill_list.html">处理报账单</a> 45 <a href="/backend/hightchart.html">老板大boss</a> 46 <hr> 47 <div class="tool"> 48 <div class="num left"> 49 <i class="fa fa-calendar" aria-hidden="true"></i> 50 搜索报障({{data_count}}篇) 51 </div> 52 <div class="add right"> 53 <a href="/backend/add_trouble.html"> 54 <i class="fa fa-plus-circle" aria-hidden="true"></i> 55 创建报障单 56 </a> 57 </div> 58 </div> 59 <hr> 60 <div class="container"> 61 <div> 62 <table class="table table-bordered table-striped"> 63 <thead> 64 <tr> 65 <th>报障标题</th> 66 <th>状态</th> 67 <th>创建时间</th> 68 <th>处理人</th> 69 <!--<th>处理时间</th>--> 70 <!--<th>评分</th>--> 71 <th>操作</th> 72 </tr> 73 </thead> 74 <tbody id="tb"> 75 {% for row in data_list %} 76 <tr nid="{{row.id}}"> 77 <td na="title">{{row.title}}</td> 78 <!--get_status_display 自动把字段status 1 转为 未处理--> 79 <td na="status">{{row.get_status_display}}</td> 80 <td na="create_date">{{row.create_date}}</td> 81 <td na="processor">{{row.processor.username}}</td> 82 <!--<td na="ptime">{{row.ptime}}</td>--> 83 <!--<td na="evaluation">{{row.evaluation}}</td>--> 84 <td> 85 <button type="button" class="btn btn-danger"> 86 <i class="fa fa-times" aria-hidden="true"></i> 87 查看 88 </button> 89 | 90 <a href="/backend/edit_trouble-{{row.id}}.html" type="button" class="btn btn-primary"> 91 <i class="fa fa-pencil-square-o" aria-hidden="true"></i> 92 编辑 93 </a> 94 </td> 95 </tr> 96 {% endfor %} 97 </tbody> 98 </table> 99 </div> 100 </div> 101 <hr> 102 <div class="right"> 103 <nav aria-label="Page navigation"> 104 <ul class="pagination"> 105 {{obj_list.page_str|safe}} 106 </ul> 107 </nav> 108 </div> 109 110 {% endblock %}
-----------------------------------------------------
1 {% extends ‘backend_layout.html‘ %} 2 3 {% block css %} 4 <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> 5 <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> 6 <link rel="stylesheet" href="/static/plugins/kindeditor/themes/default/default.css"> 7 <style> 8 .kind-content{ 9 width: 100%; 10 min-height: 500px; 11 } 12 </style> 13 {% endblock %} 14 15 {% block content %} 16 17 <form action="/backend/add_trouble.html" method="POST" novalidate> 18 {% csrf_token %} 19 <ul> 20 <li>{{form.title.label}} 21 {{form.title}} 22 {{form.errors.title.0}}</li> 23 <li>{{form.detail.label}}{{form.detail}}{{form.errors.detail.0}}</li> 24 </ul> 25 <input type="submit" value="提交"> 26 </form> 27 {% endblock %} 28 29 {% block js %} 30 31 <script charset="utf-8" src="/static/plugins/kindeditor/kindeditor-all.js"></script> 32 <script charset="utf-8" src="/static/plugins/kindeditor/lang/zh-CN.js"></script> 33 <script> 34 KindEditor.ready(function (K) { 35 var editor = K.create(‘#detail‘,{ 36 resizeType: 1 37 }) 38 }); 39 </script> 40 {% endblock %}
------------------------------------------------------
1 {% extends ‘backend_layout.html‘ %} 2 3 {% block css %} 4 <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> 5 <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> 6 <link rel="stylesheet" href="/static/plugins/kindeditor/themes/default/default.css"> 7 <style> 8 .kind-content{ 9 width: 100%; 10 min-height: 500px; 11 } 12 </style> 13 {% endblock %} 14 15 {% block content %} 16 17 <form action="/backend/edit_trouble-{{nid}}.html" method="POST" novalidate> 18 {% csrf_token %} 19 <ul> 20 <li>{{form.title.label}} 21 {{form.title}} 22 {{form.errors.title.0}}</li> 23 <li>{{form.detail.label}}{{form.detail}}{{form.errors.detail.0}}</li> 24 </ul> 25 <input type="submit" value="提交"> 26 </form> 27 {% endblock %} 28 29 30 {% block js %} 31 32 <script charset="utf-8" src="/static/plugins/kindeditor/kindeditor-all.js"></script> 33 <script charset="utf-8" src="/static/plugins/kindeditor/lang/zh_CN.js"></script> 34 <script> 35 KindEditor.ready(function (K) { 36 var editor = K.create(‘#detail‘,{ 37 resizeType: 1 38 }) 39 }); 40 </script> 41 {% endblock %}
2、管理员
url路由
1 re_path(‘^trouble_kill_list.html$‘, trouble.trouble_kill_list), 2 re_path(‘^kill_trouble-(d+).html$‘, trouble.kill_trouble),
视图函数
1 from django.db.models import Q 2 def trouble_kill_list(request): 3 current_user_id = 1 4 trouble_kill_list = models.Warning.objects.filter(Q(processor=current_user_id)|Q(status=1)).order_by(‘status‘).only(‘title‘, ‘status‘,‘submit‘,‘create_date‘,‘detail‘) 5 data_count = trouble_kill_list.count() 6 7 current_page = request.GET.get(‘p‘) 8 current_url = ‘/backend/trouble_kill_list.html‘ 9 obj_list = Pagination(trouble_kill_list.count(), current_page, current_url) 10 data_list = trouble_kill_list[obj_list.start():obj_list.end()] 11 return render(request, ‘backend_trouble_kill_list.html‘, { 12 ‘data_count‘: data_count, 13 ‘data_list‘: data_list, 14 ‘obj_list‘: obj_list, 15 }) 16 17 def kill_trouble(request,nid): 18 current_user_id = 1 19 if request.method == ‘GET‘: 20 # 判断当前用户是否进入过,以便退出后还可进入,不然第一次进入状态修改后,则无法再次进入 21 ret = models.Warning.objects.filter(id=nid,processor=current_user_id).count() 22 if not ret: 23 v = models.Warning.objects.filter(id=nid,status=1).update(status=2,processor=current_user_id) 24 if not v: 25 return HttpResponse(‘手速慢.....‘) 26 obj = models.Warning.objects.filter(id=nid).first() 27 form = TroubleForm(initial={ 28 ‘title‘:obj.title, 29 ‘detail‘:obj.detail, 30 }) 31 return render(request, ‘backend_kill_trouble.html‘,{ 32 ‘form‘:form, 33 ‘obj‘:obj, 34 ‘nid‘:nid, 35 }) 36 else: 37 # 验证是否是当前用户,防止他人伪造POST请求,恶意修改内容 38 ret = models.Warning.objects.filter(id=nid, processor=current_user_id, status=2).count() 39 if not ret: 40 return HttpResponse(‘去你大爷....‘) 41 42 form = TroubleForm(request.POST) 43 if form.is_valid(): 44 dic = {} 45 dic[‘status‘] = 3 46 dic.update(form.cleaned_data) 47 models.Warning.objects.filter(id=nid).update(**dic) 48 return redirect(‘/backend/trouble_kill_list.html‘) 49 else: 50 obj = models.Warning.objects.filter(id=nid).first() 51 return render(request, ‘backend_kill_trouble.html‘, { 52 ‘form‘: form, 53 ‘obj‘: obj, 54 ‘nid‘: nid, 55 })
模块
1 {% extends ‘backend_layout.html‘ %} 2 3 {% block css %} 4 <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> 5 <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> 6 <style> 7 .menu{ 8 height: 48px; 9 background-color: #dddddd; 10 line-height: 48px; 11 } 12 .menu a{ 13 padding: 5px; 14 } 15 .tool{ 16 height: 40px; 17 background-color: #dddddd; 18 line-height: 40px; 19 } 20 .tool .num{ 21 padding: 0 8px; 22 } 23 .tool .add{ 24 background-color: #79aec8; 25 width: 200px; 26 text-align: center; 27 } 28 .tool .add a{ 29 color: white; 30 } 31 </style> 32 {% endblock %} 33 34 {% block content %} 35 <div class="menu"> 36 <a href="#">报障管理</a> 37 | 38 处理报障列表 39 </div> 40 <hr> 41 <i class="fa fa-search" aria-hidden="true"></i> 42 <input type="text" placeholder="搜索条件"> 43 <hr> 44 <div class="tool"> 45 <div class="num left"> 46 <i class="fa fa-calendar" aria-hidden="true"></i> 47 处理报障({{data_count}}篇) 48 </div> 49 </div> 50 <hr> 51 <div class="container"> 52 <div> 53 <table class="table table-bordered table-striped"> 54 <thead> 55 <tr> 56 <th>报障标题</th> 57 <th>状态</th> 58 <th>创建时间</th> 59 <th>提交者</th> 60 <!--<th>处理时间</th>--> 61 <!--<th>评分</th>--> 62 <th>操作</th> 63 </tr> 64 </thead> 65 <tbody id="tb"> 66 {% for row in data_list %} 67 <tr nid="{{row.id}}"> 68 <td na="title">{{row.title}}</td> 69 <!--get_status_display 自动把字段status 1 转为 未处理--> 70 <td na="status">{{row.get_status_display}}</td> 71 <td na="create_date">{{row.create_date}}</td> 72 <td na="submit">{{row.submit.username}}</td> 73 <!--<td na="ptime">{{row.ptime}}</td>--> 74 <!--<td na="evaluation">{{row.evaluation}}</td>--> 75 <td> 76 <a href="/backend/kill_trouble-{{row.id}}.html" type="button" class="btn btn-primary"> 77 <i class="fa fa-pencil-square-o" aria-hidden="true"></i> 78 {% if row.status == 1 %} 79 抢单 80 {% elif row.status == 2 %} 81 抢单成功 82 {% else %} 83 查看解决方案 84 {% endif %} 85 </a> 86 | 87 <button type="button" class="btn btn-danger"> 88 <i class="fa fa-times" aria-hidden="true"></i> 89 查看 90 </button> 91 | 92 <a href="/backend/edit_trouble-{{row.id}}.html" type="button" class="btn btn-primary"> 93 <i class="fa fa-pencil-square-o" aria-hidden="true"></i> 94 编辑 95 </a> 96 </td> 97 </tr> 98 {% endfor %} 99 </tbody> 100 </table> 101 </div> 102 </div> 103 <hr> 104 <div class="right"> 105 <nav aria-label="Page navigation"> 106 <ul class="pagination"> 107 {{obj_list.page_str|safe}} 108 </ul> 109 </nav> 110 </div> 111 112 {% endblock %}
==================
1 {% extends ‘backend_layout.html‘ %} 2 3 {% block css %} 4 <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/> 5 <link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/> 6 <link rel="stylesheet" href="/static/plugins/kindeditor/themes/default/default.css"> 7 <style> 8 .kind-content{ 9 width: 100%; 10 min-height: 500px; 11 } 12 </style> 13 {% endblock %} 14 15 {% block content %} 16 <form action="/backend/kill_trouble-{{nid}}.html" method="POST" novalidate> 17 {% csrf_token %} 18 <ul> 19 <li>{{form.title.label}}{{form.title}}{{form.errors.title.0}}</li> 20 <hr> 21 <select id="tid" onchange="troubleChange();"> 22 <!--从models中取数据--> 23 <option value="1111111111111">电脑死机</option> 24 <option value="2222222222222">电脑中毒</option> 25 <option value="3333333333333">电脑蓝屏</option> 26 </select> 27 <input id="iid" type="checkbox"> 28 <hr> 29 <li>{{form.detail.label}}{{form.detail}}{{form.errors.detail.0}}</li> 30 </ul> 31 <input type="submit" value="提交"> 32 </form> 33 {% endblock %} 34 35 {% block js %} 36 37 <script charset="utf-8" src="/static/plugins/kindeditor/kindeditor-all.js"></script> 38 <script charset="utf-8" src="/static/plugins/kindeditor/lang/zh-CN.js"></script> 39 <script src="/static/JS/jquery.js"></script> 40 <script> 41 function troubleChange() { 42 //一下两种方式均可,获取select所选对应的内容 43 // .text()获取文本值 .val()获取value值 44 //var checkText = $(‘#tid‘).find("option:selected").val(); 45 var checkText = document.getElementById(‘tid‘).value; 46 //alert(checkText); 47 //判断CheckBox是否选中,选中则生效 48 var ret = $("#iid").is(‘:checked‘); 49 if ( ret ) { 50 editor = editor.html(checkText); 51 } 52 } 53 var editor = null 54 KindEditor.ready(function (K) { 55 editor = K.create(‘#detail‘,{ 56 resizeType: 1 57 }) 58 }); 59 </script> 60 {% endblock %}
3、超级管理员
url路由
1 re_path(‘^trouble_highchart.html$‘, trouble.trouble_highchart), 2 re_path(‘^trouble_report.html$‘, trouble.trouble_report),
views视图函数
1 def trouble_highchart(request): 2 return render(request, ‘backend_trouble_highchart.html‘) 3 4 from django.db import connection,connections 5 def trouble_report(request): 6 # 取出所以管理员 7 user_list = models.User.objects.filter() 8 response = [] 9 for user in user_list: 10 cursor = connection.cursor() 11 # 如何转时间戳? 12 cursor.execute("select date_format(date_format(create_date,‘%%Y-%%m-%%d‘),‘%%d‘),count(id) from repository_warning where processor_id=%s group by date_format(create_date,‘%%Y-%%m-%%d‘)", [user.id,]) 13 result = cursor.fetchall() 14 print(user.username,result) 15 tem = { 16 ‘name‘:user.username, 17 ‘data‘:result 18 } 19 response.append(tem) 20 import json 21 return HttpResponse(json.dumps(response))
template模块
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <link rel="icon" href="https://static.jianshukeji.com/highcharts/images/favicon.ico"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <style> 8 /* css 代码 */ 9 10 </style> 11 <script src="https://img.hcharts.cn/highcharts/highcharts.js"></script> 12 <script src="https://img.hcharts.cn/highcharts/modules/exporting.js"></script> 13 <script src="https://img.hcharts.cn/highcharts-plugins/highcharts-zh_CN.js"></script> 14 <script src="/static/JS/jquery.js"></script> 15 </head> 16 <body> 17 <div id="container" style="min-width:400px;height:400px"></div> 18 <script> 19 $(function () { 20 initChart(); 21 }); 22 function initChart() { 23 var config = { 24 chart: { 25 type: ‘spline‘ 26 }, 27 title: { 28 text: ‘两地月平均温度‘ 29 }, 30 subtitle: { 31 text: ‘数据来源: WorldClimate.com‘ 32 }, 33 xAxis: { 34 title: { 35 text: ‘时间‘ 36 }, 37 labels: { 38 formatter: function () { 39 return this.value; 40 } 41 } 42 }, 43 yAxis: { 44 title: { 45 text: ‘个数‘ 46 }, 47 labels: { 48 formatter: function () { 49 return this.value + ‘个‘; 50 } 51 } 52 }, 53 tooltip: { 54 crosshairs: true, 55 shared: true 56 }, 57 legend: { 58 enabled: true 59 }, 60 plotOptions: { 61 spline: { 62 marker: { 63 radius: 4, 64 lineColor: ‘#666666‘, 65 lineWidth: 1 66 } 67 } 68 }, 69 exporting: { 70 enabled: false 71 }, 72 series: [ 73 { 74 name: ‘东京‘, 75 marker: { 76 symbol: ‘square‘ 77 }, 78 data: [ 79 [0, 15], 80 [10, -50], 81 [20, -56.5], 82 [30, -46.5] 83 ] 84 }, 85 { 86 name: ‘伦敦‘, 87 marker: { 88 symbol: ‘diamond‘ 89 }, 90 data: [ 91 [0, 15], 92 [5, -50], 93 [20, -56.5], 94 [30, -46.5] 95 ] 96 } 97 ] 98 } 99 100 //数据库中获取series 101 $.ajax({ 102 url: ‘/backend/trouble_report.html‘, 103 dataType: ‘json‘, 104 success: function(arg) { 105 config[‘series‘] = arg; 106 Highcharts.chart(‘container‘,config); 107 } 108 }); 109 } 110 111 </script> 112 </body> 113 </html>
以上是关于西游之路——python全栈——报障系统之后台管理的主要内容,如果未能解决你的问题,请参考以下文章