前言
来看一段代码
def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
直接把HTML页面嵌套在视图函数里返回给浏览器并不是一个好主意;
原因:
1、对页面设计进行的任何改变都必须对 Python 代码进行相应的修改,牵一发而动全身;
2、Python 代码编写和 HTML 设计是两项不同的工作,前端开发和后端开发无非 并行;
基于这些原因,将HTML页面的设计和后端逻辑设计分离,会更简洁、容易维护开发我们的WEB应用。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式,这就是本章要具体讨论的问题。
模板是什么?
Django自带的模板语言= HTML代码+逻辑控制代码,注意 模板 != HTML,模块 =HTML代码+逻辑控制代码(特殊标记);
模板作用?
在server端 把后端的变量 嵌入到HTML中渲染后,返回给浏览器来达到前后端代码分离,页面动态显示的目的;
一、Django模板语言应用:
Django模板语言的语法主要分为2种: {{变量}} 和 {% Tag %} ,{{变量 }}主要用于和视图变量做替换,{% tag %}主要用于做逻辑判断和实现某些功能,正因有了数据+逻辑才构成了模板语言;
1.1、使用双大括号引用视图中的变量
语法:{{ 变量}} ,列表取值:{{列表}}. 索引, 字典取值:{{字典}}.键
<td>{{ forloop.counter }}</td> <td>{{ book.title }}</td> <td>{{ book.price }}</td> <td>{{ book.date}}</td> <td>{{ book.publish}}</td> <td>{{ book.author }}</td>
** {{ forloop.counter }} 渲染循环的次数
1.2:内置变量过滤器的使用
如果引用得视图变量,不能直接渲染使用,可以借助fifter进行数据的二次处理,就像Python中的内置函数;
语法:{{ 变量|fifter:参数 }}
过滤器列表:
- add:给变量加上相应的值、
- addslashes :单引号加上转义号,一般用于输出到javascript中
- capfirst :第一个字母大写
- {{ "123spam456spam789"|cut:"spam" }}查找删除指定的字符串
- {{ l1|slice:":2" }} 列表切边
- {{ t|date:'Y-m-d' }} 转换特定时间格式
- {{ s|default:'空空如也' }} 值不存在,使用指定值
- {{ info|truncatechars:18 }} 渲染指定长度的字符
- {{ info1|truncatewords:9 }}渲染指定长度的单词
- {{ a|safe }} 声明安全可以渲染
- {% if forloop.counter|divisibleby:2 %} 整除
实例
视图
from django.shortcuts import render import datetime def fifters(request): i=10 w="A'B'C'D'E" f='china' t=datetime.datetime.now() s='' l1=[98890,765,9870,7654] info='嘲笑我吧你们这些毫无眼光的人,我必将引来雷霆万钧的力量,摧古拉朽得战胜一切敌人!' info1='You laugh at me without the vision of people, and I will lead to an irresistible force power, corruption must defeat all enemies destroy gura!' li=['a','b','c','d','e','f','g'] str1='{{hello world}}' a='<a href="黄色网址">点击我</a>' fhjsaldfhjsdfhlasdfhljsdal='hellow world' return render(request,'modals.html',locals())
模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模板渲染</title> </head> <body> <p>{{ i|add:200 }}</p> <p>{{ w|addslashes}}</p> <p>{{ f|capfirst }}</p> <p>{{ "123spam456spam789"|cut:"spam" }}</p> <p>{{ t|date:'Y-m-d' }}</p> <p>{{ l1|slice:":2" }}</p> <p>{{ s|default:'空空如也' }}</p> <p>{{ info|truncatechars:18 }}</p> <p>{{ info1|truncatewords:9 }}</p> <p> {% csrf_token%} {% for foo in li %} <li>{{ forloop.counter0 }}----->{{ foo }}</li> {% empty %} <li>没有符合的对象</li> {% endfor %} </p> <p> {% verbatim %} {{ str1 }} {% endverbatim %} </p> <p> {% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %} </p> <p>{{ a|safe }}</p> </body> </html> 更多参考:豆瓣:https://www.douban.com/note/145065606/,袁浩:http://www.cnblogs.com/sss4/p/7071183.html
2.1、内置标签(tag)的使用
如果引用到了视图中的变量,还不足以渲染出一个完美的页面,那就要借助tag标签,做逻辑控制和功能完善了;
语法格式: {% tags %}
{% for %} {% endfor %} for循环
{% for row in list %} </tr> <td>{{ row.id }}</td> <td>{{ row.name }}</td> <td>{{ row.title }}</td> <td><a href="#" onclick="show_modal(this)">添加</a></td> <td id="del_s"><a href="#" onclick="modal_del(this)">删除</a> </td> <td><a href="#"onclick="modal_edit(this)">编辑</a></td> </tr> {% endfor %}
{% if %}{% endfor %} if判断
<select name="class_id" id=""> {% for row in dict %} {% if row.id == name1.class_id %} <option selected value="{{ row.id }}">{{ row.title}}</option> {%else%} <option value="{{ row.id }}">{{ row.title}}</option> {%endif%} {% endfor %} </select>
{% if row.id in cids%} in 成员关系判断
<p>任教课程: <select name="class_id" multiple size="5"> {% for row in clas %} {% if row.id in cids%} <option selected value={{ row.id}}>{{ row.title}}</option> {%else%} <option value={{ row.id}}>{{ row.title}}</option> {% endif %} {% endfor %} </select> </p>
{% empty %} 没有渲染到数据,提示。
{% for foo in li %} <li>{{ forloop.counter0 }}----->{{ foo }}</li> {% empty %} <li>没有符合的对象</li> {% endfor %}
{% verbatim %}{% endverbatim %} 禁止渲染
视图
str1='{{hello world}}'
模板
{% verbatim %}
{{ str1 }}
{% endverbatim %}
{% csrf_token %}
用于生成csrf_token的标签,用于防治跨站攻击验证(csrf)。 其实,这里是会生成一个input标签,和其他表单标签一起提交给后台的。
{% url %} 引用路由分配系统配置的 path 别名
<form action="{% url "bieming"%}" > <input type="text"> <input type="submit"value="提交"> {%csrf_token%} </form>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p>{{args}}</p> <p>{% url "zhangge" i i1%}</p> </body> </html>
{% with %} {% endwith %} 用更简单的变量名 替代视图复杂的变量名
fhjsaldfhjsdfhlasdfhljsdal='hellow world' 把后端复杂的变量名,转换得更加简单; <p> {% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %} </p>
在标签里添加reversed来反序循环列表
{% for log in logs reversed %} {% if forloop.counter|divisibleby:2 %} <dl> <dd class="pos-right clearfix"> <div class="circ"></div> <!--圆圈--> <div class="time"><p>{{ log.update_time }}</p></div> <!--时间--> <div class="events"> <div class="events-header"> <p>{{ log.details }}</p> </div> <div class="events-footer"> <span>{{ log.verbose_content }}</span> </div> </div> <!--内容 --> </dd> </dl> <!--通过设置class="pos-方向clearfix" --> {% else %}
二、自定义fifter和simp-tag
模板语言自带的tag和过滤器,在某些情况下还不能满足我的功能需求,例如无法实现递归显示需求等,可以自定义fifter和tag;就像Python内置函数和自定义函数关系;
1、在app中创建 templatetags目录或Python包(注意 该报的名称必须为 templatetags)
2、templatetags文件夹下随便创建个Python文件,自定义函数;
from django import template register=template.Library() @register.filter #自定义fifter 就使用 fifter装饰器 def mutil(x,y): return x*y @register.simple_tag #自定义tag 就使用 simlep_tag装饰器 def mutil2(x,y,z): return x*y*z
3、注册到setings.py文件里
4、加载到模板里
{% load mytag %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模板渲染</title> </head>
5、引用到模板
a.
{{ i| mutil:10 }} #自定义fifter的使用
{% mutil2 78 90 20 %} #自定义tag的使用
b.注意引用到 母版继承的模板
{% extends "arya/layout.html" %} {% load Count %} #------------------》注意在子模板的 extends之下。
{% block content %}
6、自定义fifter和simp-tag 区别
1、simple-fifter
优点:支持iif else 条件判断
{% if i|mutil:20 > 100 %} <p>大于</p> {% else %} }} <p>小于</p> {% endif %}
缺点:simple-fifter类型的函数只支持2两个参数
2、simple-tag
优点:simple-fifter类型 无限制传参
{% mutil2 78 90 20 %} #参数无限制
缺点:不支持iif else 条件判断
三、母版继承
在整个网站中,如何减少共用页面区域(比如站点导航)所引起的重复和冗余代码?Django 解决此类问题的首选方法是使用一种优雅的策略—— 模板继承 。
本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。
子模板 继承、重写 母板的block内容;
1、母版定义block块:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>后台布局</title> <style> .header{ width: 100%; height: 48px; background-color: blue; position: fixed; top: 0px; left: 0px; } .left{ width: 200px; background-color: mediumvioletred; position: fixed; top: 48px; left: 0px; bottom: 0px; } {# 要想设置长度沾满屏,就设置position: fixed ,bottom: 0px;#} .right{ background-color: pink; position: fixed; top: 48px; left: 200px; bottom: 0px; right: 0px; overflow: scroll; } .title li{ margin-top: 80px; } </style> </head> <body> <div class="content"> <div class="header"></div> <div class="left"> <ul class="title" style="list-style-type:none"> <li><a href="/menu1/">菜单1</a></li> <li><a href="/menu2/">菜单2</a></li> <li><a href="/menu3/">菜单3</a></li> </ul> </div> <div class="right"> {% block con %} {% endblock %} </div> </div> </body> </html>
2、子版继承母版中 block
{% extends 'base.html' %} {% block con %} <h1>菜单{{ id }}</h1> <h1>菜单{{ id }}</h1> <h1>菜单{{ id }}</h1> <h1>菜单{{ id }}</h1> <h1>菜单{{ id }}</h1> <h1>菜单{{ id }}</h1> {% endblock %}
扩展:
模板的CSS样式和JS代码不完全是子版想要继承的怎么办?
模板的定义的block越多越好,这样就可以多处重写母版样式;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>后台布局</title> <style> .header{ width: 100%; height: 48px; background-color: blue; position: fixed; top: 0px; left: 0px; } .left{ width: 200px; background-color: mediumvioletred; position: fixed; top: 48px; left: 0px; bottom: 0px; } {# 要想设置长度沾满屏,就设置position: fixed ,bottom: 0px;#} .right{ background-color: pink; position: fixed; top: 48px; left: 200px; bottom: 0px; right: 0px; overflow: scroll; } .title li{ margin-top: 80px; } </style> {% block css1 %} {% endblock %} </head> <body> <div class="content"> <div class="header"></div> <div class="left"> <ul class="title" style="list-style-type:none"> <li><a href="/menu1/">菜单1</a></li> <li><a href="/menu2/">菜单2</a></li> <li><a href="/menu3/">菜单3</a></li> </ul> </div> <div class="right"> {% block con %} {# #这样子版就可以重写母版的CSS样式了,重载JavaScript亦是如此!#} {% endblock %} </div> </div> </body> </html>
例如:
1.先创建一个base.htm 用来引入站点都要用到的 jQuery、bootstrap;
2.head设置 outside_css、outside_js块让其他模板引入外部文件;
3.body设置content块让其他模板嵌套内容;
4.button the body and the html中间设置 inside块让用户扩展自己的JavaScript代码;
这么做的好处: 可以减少代码冗余、提升代码重用性、减少外部JavaScript文件的反复引入耗时,也可以分门别类的管理外部引入文件,避免引入外部文件过多时。容易出现的引入新文件不生效、生效了页面显示错误......这些头令人头疼的问题;
<!DOCTYPE html> <html lang="en"> <head> <title>运维管理平台-面板</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta charset="UTF-8"/> <!-- jQuery相关开始 注意不要在全局再次引入jQuery --> <script src="/static/assets/js/jquery.js"></script> <!-- jQuery相关结束 --> <!-- bootstarp相关开 --> <link href="/static/bootstrap/css/bootstrap.css" rel="stylesheet"> <script src="/static/bootstrap/js/bootstrap.js"></script> <!-- bootstarp相关结束--> <!-- redis可视化相关开始--> <link rel="stylesheet" href="https://cdn.bootcss.com/jqueryui/1.12.1/jquery-ui.css"> <script src="https://cdn.bootcss.com/jqueryui/1.12.1/jquery-ui.js"></script> <script src="/static/pligin/jquery-validation-1.14.0/dist/jquery.validate.min.js"></script> <script src="/static/pligin/jquery-validation-1.14.0/dist/additional-methods.min.js"></script> <script src="/static/pligin/jquery-validation-1.14.0/dist/localization/messages_zh.min.js"></script> <script src="/static/pligin/jquery.form.min.js"></script> <!-- redis可视化相关结束--> <link href="/static/assets/font-awesome-4.7.0/css/font-awesome.css" rel="stylesheet"> <link rel="stylesheet" href="/static/assets/css/vendor/animate/animate.min.css"> <link type="text/css" rel="stylesheet" media="all" href="/static/assets/js/vendor/mmenu/css/jquery.mmenu.all.css"/> <link rel="stylesheet" href="/static/assets/js/vendor/videobackground/css/jquery.videobackground.css"> <link rel="stylesheet" href="/static/assets/css/vendor/bootstrap-checkbox.css"> <link rel="stylesheet" href="/static/assets/js/vendor/rickshaw/css/rickshaw.min.css"> <link rel="stylesheet" href="/static/assets/js/vendor/morris/css/morris.css"> <link rel="stylesheet" href="/static/assets/js/vendor/tabdrop/css/tabdrop.css"> <link rel="stylesheet" href="/static/assets/js/vendor/summernote/css/summernote.css"> <link rel="stylesheet" href="/static/assets/js/vendor/summernote/css/summernote-bs3.css"> <link rel="stylesheet" href="/static/assets/js/vendor/chosen/css/chosen.min.css"> <link href="/static/assets/css/minimal.css" rel="stylesheet"> <style> #weixin { margin-top: 10%; text-align: center; } #weixin1 { width: 120px; height: 120px; } #weixin2 { } <!-- 头像选择开始 --> .my_box { width: 75px; height: 75px; overflow: hidden; border-radius: 15px; border: 1px solid #ccc; position: fixed; left: 0; right: 0; top: 0; bottom: 0; margin: auto; transition: .6s; cursor: pointer; } .my_box:hover { animation: my_box 0.5s forwards; transition: .5s; } @keyframes my_box { form { transform: rotate(0deg); } to { transform: rotate(360deg); } } .my_box img { width: 100%; } .xiantiao { display: block; width: 86%; height: 1px; border-bottom: 1px solid #ccc; margin: 0 auto; } .pic_box { width: 609px; min-height: 673px; height: auto; border-radius: 8px; background: #fff; border: 1px solid #ccc; position: fixed; top: -1000px; left: 0; right: 0; margin: 0 auto; } .header { height: 45px; text-align: center; } .close { color: #000; font-size: 21px; line-height: 1; text-shadow: 0 1px 0 #fff; opacity: .2; position: absolute; right: 8px; top: 2px; cursor: pointer; } .pic_box ul { padding: 0; margin: 0; width: 96%; height: 511px; margin: 10px auto; } .pic_box ul li { display: block; list-style: none; width: 61px; height: 61px; float: left; border-radius: 15%; border: 1px solid #ccc; margin: 5px 5px; transition: .6s; cursor: pointer; overflow: hidden; } .pic_box ul li:hover { transform: scale(1.15); transition: .5s; } .pic_box ul li img { width: 100%; } .bt_box { width: 100%; text-align: center; font-size: 14px; margin-top: 30px; } .bt_box .gb { display: inline-block; width: 120px; height: 35px; border-radius: 8px; background: #f3f3f3; color: #444; line-height: 35px; } .bt_box .queren { display: inline-block; width: 120px; height: 35px; border-radius: 8px; background: #4B8BF5; color: #fff; line-height: 35px; } @import url("https://fonts.googleapis.com/css?family=Lato"); *, *:before, *:after { /* Slow, yes I know :) */ -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } </style> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <![endif]--> {% block out_css %} {% endblock %} {% block out_js %} {% endblock %} </head> {% block body %} your body content {% endblock %} {% block in_js %} {% endblock %} </html>
{% extends 'base.html' %} {% load menu %} {% load rbac %} {% load Count %} {% block body %} <body class="bg-3"> <!-- 预加载 --> <div class="mask"> <div id="loader"></div> </div> <!--预加载 --> <!-- 这里包装所有页面内容 --> <div id="wrap"> <!-- Make page fluid --> <div class="row"> <!-- 固定导航栏 --> <div class="navbar navbar-default navbar-fixed-top navbar-transparent-black mm-fixed-top" role="navigation" id="navbar"> <!-- 标题 --> <div class="navbar-header col-md-2"> <a class="navbar-brand" href="/login_first/"> <strong>ITGroupⅡ</strong>运维平台 </a> <div class="sidebar-collapse"> <a href="#"> <i class="fa fa-bars"></i> </a> </div> </div> <!-- 标题 end --> <!-- .nav-collapse --> <div class="navbar-collapse"> <!-- Page refresh --> <ul class="nav navbar-nav refresh"> <li class="divided"> <a href="#" class="page-refresh"><i class="fa fa-refresh"></i></a> </li> </ul> <!-- /Page refresh --> <!-- Search --> <div class="search" id="main-search"> <form method='GET'> <input type="text" name="q" value="{{ pw.q_value }}" placeholder="搜索"/> </div> <input type="submit" value="搜索" class="btn btn-warning btn-sm"/> </form> <!-- Search end --> <!-- Quick Actions --> <ul class="nav navbar-nav quick-actions"> <li class="dropdown divided"> <div> <h4>值班人员:{{ request.session.user_info.username|WhoDutyOfficer }} 联系电话:{{ request.session.user_info.username|WhoDutyPhoneOfficer }}</h4> </div> </li> <li class="dropdown divided user" id="current-user"> <div class="profile-photo"> <div class="wrap"> <a class="t"></a> <div class="my_box"> <form id="uploadForm"> <input class="jide" name="imgsrc" type="hidden" value=""/> <img src="{{ request.session.Avatar }}" class="my_pic" style="width: 45px;height: 45px;overflow: hidden;border-radius: 50%"/> </form> </div> <div class="pic_box" id="pic_box"> <div class="header"> <p>设置头像</p> <span class="close">x</span> </div> <span class="xiantiao"></span> <ul> <li><img src="/static/img/touxiang/0.png"/></li> <li><img src="/static/img/touxiang/1.png"/></li> <li><img src="/static/img/touxiang/3.png"/></li> <li><img src="/static/img/touxiang/4.png"/></li> <li><img src="/static/img/touxiang/5.png"/></li> <li><img src="/static/img/touxiang/6.png"/></li> <li><img src="/static/img/touxiang/7.png"/></li> </ul> <div class="bt_box"> <a class="gb" href="javascript:">关闭</a> <a class="queren" href="javascript:">保存头像</a> </div> </div> </div> </div> <a class="dropdown-toggle options" data-toggle="dropdown" href="#"> {{ request.session.user_info.username }} <i class="fa fa-caret-down"></i> </a> <ul class="dropdown-menu arrow settings"> <li> <h3>背景色:</h3> <ul id="color-schemes"> <li><a href="#" class="bg-1"></a></li> <li><a href="#" class="bg-2"></a></li> <li><a href="#" class="bg-3"></a></li> <li><a href="#" class="bg-4"></a></li> <li><a href="#" class="bg-5"></a></li> <li><a href="#" class="bg-6"></a></li> </ul> </li> <li> <a href="/login_first/changepwd/"><i class="fa fa-user"></i> 修改密码</a> </li> <li> <a href="/login"><i class="fa fa-power-off"></i> 退出</a> </li> </ul> </li> <li> <a href="#mmenu"><i class="fa fa-comments"></i></a> </li> </ul> <!-- /Quick Actions --> <ul class=""> <li class="dropdown divided"> <div class="box"> <div class="t_news"> <ul class="news_li" id="liliok"> </ul> <ul class="swap"></ul> </div> </div> </li> </ul> <!-- 左侧菜单 --> <ul class="nav navbar-nav side-nav" id="sidebar"> <li class="collapsed-content"> <ul> <li class="search"><!-- Collapsed search pasting here at 768px --></li> </ul> </li> <li class="navigation" id="navigation"> <a href="#" class="sidebar-toggle" data-toggle="#navigation">导航 <i class="fa fa-angle-up"></i></a> <ul class="menu"> <li class="active"> <a href="/login_first/"> <i class="fa fa-tachometer"></i> 首页 {# <span class="badge badge-red">1</span>#} </a> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <i class="fa fa-list"></i> 主机管理 <b class="fa fa-plus dropdown-plus"></b> </a> <ul class="dropdown-menu"> <li> <a href="/arya/cmdb/hosts/"> <i class="fa fa-caret-right"></i> 主机列表 </a> </li> <li> <a href="/arya/cmdb/hosts/add/"> <i class="fa fa-caret-right"></i> 新增主机 </a> </li> <li> <a href="/multitask/command/"> <i class="fa fa-caret-right"></i> 命令执行 </a> </li> <li> <a href="/multitask/transfer_files/"> <i class="fa fa-caret-right"></i> 文件上传 </a> </li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <i class="fa fa-list"></i> 监控管理 <b class="fa fa-plus dropdown-plus"></b> </a> <ul class="dropdown-menu"> <li> <a href="/arya/cmdb/zabbixmsg/"> <i class="fa fa-caret-right"></i> 监控列表 </a> </li> <li> <a href="/arya/cmdb/zabbixmsg/add/"> <i class="fa fa-caret-right"></i> 添加监控 </a> </li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <i class="fa fa-list"></i> 工单管理 <b class="fa fa-plus dropdown-plus"></b> </a> <ul class="dropdown-menu"> <li> <a href="/arya/cmdb/worker_order/"> <i class="fa fa-caret-right"></i> 工单列表 </a> </li> <li> <a href="/arya/cmdb/worker_order/?selected_info=alarm_info"> <i class="fa fa-caret-right"></i> 报警列表 </a> </li> <li> <a href="/arya/cmdb/track_work/"> <i class="fa fa-caret-right"></i> 跟进工单 </a> </li> <li> <a href="/arya/cmdb/worker_order/active_creation/"> <i class="fa fa-caret-right"></i> 创建工单 </a> </li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <i class="fa fa-list"></i> DB可视化 <b class="fa fa-plus dropdown-plus"></b> </a> <ul class="dropdown-menu"> <li> <a href="/DBshow/redisIndex/"> <i class="fa fa-caret-right"></i> redis可视化 </a> </li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <i class="fa fa-list"></i> 图表管理 <b class="fa fa-plus dropdown-plus"></b> </a> <ul class="dropdown-menu"> <li> <a href="/chart/"> <i class="fa fa-caret-right"></i> 图表预览 </a> </li> <li> <a href="/chartdown/"> <i class="fa fa-caret-right"></i> 图表导出 </a> </li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <i class="fa fa-list"></i> 权限管理 <b class="fa fa-plus dropdown-plus"></b> </a> <ul class="dropdown-menu"> <li> <a href="/arya/cmdb/userinfo/"> <i class="fa fa-caret-right"></i> 人员列表 </a> </li> <li> <a href="/arya/rbac/menu/"> <i class="fa fa-caret-right"></i> 菜单权限 </a> </li> <li> <a href="/arya/rbac/group/"> <i class="fa fa-caret-right"></i> 分组权限 </a> </li> <li> <a href="/arya/rbac/user/"> <i class="fa fa-caret-right"></i> 用户权限 </a> </li> <li> <a href="/arya/rbac/role/"> <i class="fa fa-caret-right"></i> 角色权限 </a> </li> <li> <a href="/arya/rbac/permission/"> <i class="fa fa-caret-right"></i> URL权限 </a> </li> </ul> </li> </ul> </li> <li class="settings" id="general-settings"> <a href="#" class="sidebar-toggle underline" data-toggle="#general-settings">General Settings <i class="fa fa-angle-up"></i></a> <div id="weixin"> <h4 id="weixin2"><strong>关注运维平台</strong></h4> <img src="/static/img/qrcode_258.png.jpeg" alt="" id="weixin1"> </div> </div> </div> <!-- Fixed navbar end --> <!-- Page content --> <div id="content" class="col-md-12"> <!-- content main container --> <div class="main"> {% block content %} {% endblock %} </div> </div> <!-- 右侧缩进框--> <div id="mmenu" class="right-panel"> <!-- Nav tabs --> <ul class="nav nav-tabs nav-justified"> <li class="active"><a href="#mmenu-users" data-toggle="tab"><i class="fa fa-users"></i></a></li> </ul> <!-- Tab panes --> <div class="tab-content"> <div class="tab-pane active" id="mmenu-users"> <h5><strong>Online</strong> Users</h5> <ul class="users-list"> <li class="online"> <div class="media"> <a class="pull-left profile-photo" href="#"> <img class="media-object" src="/static/img/moren.jpg" style="width: 45px;height: 45px;overflow: hidden"> </a> <div class="media-body"> <h6 class="media-heading"> <strong>{{ request.session.user_info.username }}</strong> </h6> <small><i class="fa fa-map-marker"></i> China, beijing</small> <span class="badge badge-outline status"></span> </div> </div> </li> </ul> <h5><strong>All</strong> Users</h5> <ul class="users-list"> {% for user in userlist %} <li class="offline"> <div class="media"> <a class="pull-left profile-photo" href="#"> <img class="media-object" src="/static/img/moren.jpg" style="width: 45px;height: 45px;overflow: hidden"> </a> <div class="media-body"> <h6 class="media-heading"><strong>{{ user.username }}</strong></h6> <small><i class="fa fa-map-marker"></i> China, beijing</small> <span class="badge badge-outline status"></span> </div> </div> </li> {% endfor %} </ul> </div> </div><!-- tab-content --> </div> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <!-- Include all compiled plugins (below), or include individual files as needed --> <script type="text/javascript" src="/static/assets/js/vendor/mmenu/js/jquery.mmenu.min.js"></script> <script type="text/javascript" src="/static/assets/js/vendor/sparkline/jquery.sparkline.min.js"></script> <script type="text/javascript" src="/static/assets/js/vendor/nicescroll/jquery.nicescroll.min.js"></script> <script type="text/javascript" src="/static/assets/js/vendor/animate-numbers/jquery.animateNumbers.js"></script> <script type="text/javascript" src="/static/assets/js/vendor/videobackground/jquery.videobackground.js"></script> <script type="text/javascript" src="/static/assets/js/vendor/blockui/jquery.blockUI.js"></script> <script src="/static/assets/js/vendor/flot/jquery.flot.min.js"></script> <script src="/static/assets/js/vendor/flot/jquery.flot.time.min.js"></script> <script src="/static/assets/js/vendor/flot/jquery.flot.selection.min.js"></script> <script src="/static/assets/js/vendor/flot/jquery.flot.animator.min.js"></script> <script src="/static/assets/js/vendor/flot/jquery.flot.orderBars.js"></script> <script src="/static/assets/js/vendor/easypiechart/jquery.easypiechart.min.js"></script> <script src="/static/assets/js/vendor/rickshaw/raphael-min.js"></script> <script src="/static/assets/js/vendor/rickshaw/d3.v2.js"></script> <script src="/static/assets/js/vendor/rickshaw/rickshaw.min.js"></script> <script src="/static/assets/js/vendor/morris/morris.min.js"></script> <script src="/static/assets/js/vendor/tabdrop/bootstrap-tabdrop.min.js"></script> <script src="/static/assets/js/vendor/summernote/summernote.min.js"></script> <script src="/static/assets/js/minimal.min.js"></script> <link rel="stylesheet" href="/static/jq22.css"> <script src="/static/jq22.js"></script> <script> $(function () { // Initialize card flip $('.card.hover').hover(function () { $(this).addClass('flip'); }, function () { $(this).removeClass('flip'); }); // Initialize flot chart var d1 = [[1, 715], [2, 985], [3, 1525], [4, 1254], [5, 1861], [6, 2621], [7, 1987], [8, 2136], [9, 2364], [10, 2851], [11, 1546], [12, 2541] ]; var d2 = [[1, 463], [2, 578], [3, 327], [4, 984], [5, 1268], [6, 1684], [7, 1425], [8, 1233], [9, 1354], [10, 1200], [11, 1260], [12, 1320] ]; var months = ["January", "February", "March", "April", "May", "Juny", "July", "August", "September", "October", "November", "December"]; // flot chart generate var plot = $.plotAnimator($("#statistics-chart"), [ { label: 'Sales', data: d1, lines: {lineWidth: 3}, shadowSize: 0, color: '#ffffff' }, { label: "Visits", data: d2, animator: {steps: 99, duration: 500, start: 200, direction: "right"}, lines: { fill: .15, lineWidth: 0 }, color: ['#ffffff'] }, { label: 'Sales', data: d1, points: {show: true, fill: true, radius: 6, fillColor: "rgba(0,0,0,.5)", lineWidth: 2}, color: '#fff', shadowSize: 0 }, { label: "Visits", data: d2, points: { show: true, fill: true, radius: 6, fillColor: "rgba(255,255,255,.2)", lineWidth: 2 }, color: '#fff', shadowSize: 0 } ], { xaxis: { tickLength: 0, tickDecimals: 0, min: 1, ticks: [[1, "JAN"], [2, "FEB"], [3, "MAR"], [4, "APR"], [5, "MAY"], [6, "JUN"], [7, "JUL"], [8, "AUG"], [9, "SEP"], [10, "OCT"], [11, "NOV"], [12, "DEC"]], font: { lineHeight: 24, weight: "300", color: "#ffffff", size: 14 } }, yaxis: { ticks: 4, tickDecimals: 0, tickColor: "rgba(255,255,255,.3)", font: { lineHeight: 13, weight: "300", color: "#ffffff" } }, grid: { borderWidth: { top: 0, right: 0, bottom: 1, left: 1 }, borderColor: 'rgba(255,255,255,.3)', margin: 0, minBorderMargin: 0, labelMargin: 20, hoverable: true, clickable: true, mouseActiveRadius: 6 }, legend: {show: false} }); $(window).resize(function () { // redraw the graph in the correctly sized div plot.resize(); plot.setupGrid(); plot.draw(); }); $('#mmenu').on( "opened.mm", function () { // redraw the graph in the correctly sized div plot.resize(); plot.setupGrid(); plot.draw(); } ); $('#mmenu').on( "closed.mm", function () { // redraw the graph in the correctly sized div plot.resize(); plot.setupGrid(); plot.draw(); } ); // tooltips showing $("#statistics-chart").bind("plothover", function (event, pos, item) { if (item) { var x = item.datapoint[0], y = item.datapoint[1]; $("#tooltip").html('<h1 style="color: #418bca">' + months[x - 1] + '</h1>' + '<strong>' + y + '</strong>' + ' ' + item.series.label) .css({top: item.pageY - 30, left: item.pageX + 5}) .fadeIn(200); } else { $("#tooltip").hide(); } }); //tooltips options $("<div id='tooltip'></div>").css({ position: "absolute", //display: "none", padding: "10px 20px", "background-color": "#ffffff", "z-index": "99999" }).appendTo("body"); //generate actual pie charts $('.pie-chart').easyPieChart(); //server load rickshaw chart var graph; var seriesData = [[], []]; var random = new Rickshaw.Fixtures.RandomData(50); for (var i = 0; i < 50; i++) { random.addData(seriesData); } graph = new Rickshaw.Graph({ element: document.querySelector("#serverload-chart"), height: 150, renderer: 'area', series: [ { data: seriesData[0], color: '#6e6e6e', name: 'File Server' }, { data: seriesData[1], color: '#fff', name: 'Mail Server' } ] }); var hoverDetail = new Rickshaw.Graph.HoverDetail({ graph: graph, }); setInterval(function () { random.removeData(seriesData); random.addData(seriesData); graph.update(); }, 1000); // Morris donut chart Morris.Donut({ element: 'browser-usage', data: [ {label: "Chrome", value: 25}, {label: "Safari", value: 20}, {label: "Firefox", value: 15}, {label: "Opera", value: 5}, {label: "Internet Explorer", value: 10}, {label: "Other", value: 25} ], colors: ['#00a3d8', '#2fbbe8', '#72cae7', '#d9544f', '#ffc100', '#1693A5'] }); $('#browser-usage').find("path[stroke='#ffffff']").attr('stroke', 'rgba(0,0,0,0)'); //sparkline charts $('#projectbar1').sparkline('html', {type: 'bar', barColor: '#22beef', barWidth: 4, height: 20}); $('#projectbar2').sparkline('html', {type: 'bar', barColor: '#cd97eb', barWidth: 4, height: 20}); $('#projectbar3').sparkline('html', {type: 'bar', barColor: '#a2d200', barWidth: 4, height: 20}); $('#projectbar4').sparkline('html', {type: 'bar', barColor: '#ffc100', barWidth: 4, height: 20}); $('#projectbar5').sparkline('html', {type: 'bar', barColor: '#ff4a43', barWidth: 4, height: 20}); $('#projectbar6').sparkline('html', {type: 'bar', barColor: '#a2d200', barWidth: 4, height: 20}); // sortable table $('.table.table-sortable th.sortable').click(function () { var o = $(this).hasClass('sort-asc') ? 'sort-desc' : 'sort-asc'; $('th.sortable').removeClass('sort-asc').removeClass('sort-desc'); $(this).addClass(o); }); //todo's $('#todolist li label').click(function () { $(this).toggleClass('done'); }); // Initialize tabDrop $('.tabdrop').tabdrop({text: '<i class="fa fa-th-list"></i>'}); //load wysiwyg editor $('#quick-message-content').summernote({ toolbar: [ //['style', ['style']], // no style button ['style', ['bold', 'italic', 'underline', 'clear']], ['fontsize', ['fontsize']], ['color', ['color']], ['para', ['ul', 'ol', 'paragraph']], ['height', ['height']], //['insert', ['picture', 'link']], // no insert buttons //['table', ['table']], // no table button //['help', ['help']] //no help button ], height: 143 //set editable area's height }); //multiselect input $(".chosen-select").chosen({disable_search_threshold: 10}); }); <!-- 头像选择开始--> $(".close,.gb").click(function () { $(".pic_box").animate({ 'top': '-1000px' }, 500); }), $(".my_box").click(function () { $(".pic_box").animate({ 'top': '15px', }, 300); }), $(".queren").click(function () { var src = $(".jide").val(); $.ajax({ url: '/login_first/', type: 'post', data: {'imgsrc': src, 'csrfmiddlewaretoken': '{{ csrf_token }}'}, success: function (data) { if (data == 'OK') { window.location.reload() } } }); //$.ajax与index.php交互,在php中判断文件,保存至数据库即可 /*if(src != ""){ $.ajax({ url:"index.php", type:'post', data:{'imgsrc':src}, success:function(data){ $(".my_pic").attr('src',src); $(".pic_box").animate({ 'top':'-1000px' },500); console.log(data); } }) }else{ return false; }*/ /** * 后台我是用Thinkphp框架写的代码如下 $show=M('user')->getByusername($_SESSION['_username']); if(!empty($_POST['imgsrc'])){ $_POST['id']=$show['id']; $x=$info->create(); $res=$info->save(); if($res){ echo json_encode($_POST['imgsrc']); } } */ //效果展示,在服务器中把这一段删除,用上面那一段 if (src != "") { $(".my_pic").attr('src', src); $(".pic_box").animate({ 'top': '-1000px' }, 500); } else { return false; } }); var $box = document.getElementById('pic_box'); var $li = $box.getElementsByTagName('li'); var index = 0; for (var i = 0; i < $li.length; i++) { $li[i].index = i; $li[i].onclick = function () { $li[index].style.borderRadius = "15%"; this.style.borderRadius = "50%"; index = this.index; } } $(".pic_box li img").click(function () { var src = $(this).attr("src"); $(".jide").val(src); }); $.ajax({ url: '/list_trackwork_api/', type: 'post', data: {'csrfmiddlewaretoken': '{{ csrf_token }}'}, success: function (data) { var data = JSON.parse(data); var link1 = null; var seach1 = null; var title1 = null; $.each(data, function (i, v) { var lilili = ''; $.each(v, function (k1, v1) { if (k1 == 'link') { link1 = v1 } if (k1 == 'seach') { seach1 = v1 } if (k1 == 'title') { title1 = v1 } lilili = '<li><a href="' + link1 + '"><b>' + seach1 + ':' + title1 + '</b></a></li>'; }); $('#liliok').append(lilili); }); } }) </script> </body> {% endblock %} {#</html>#}
{% extends "arya/layout.html" %} {% block out_js %} <script src="/static/pligin/nifty/nifty.min.js"></script> {% endblock %} {% block content %} {% include 'components/hostgroups.html' %} <div class="col-lg-9"> <div class="panel"> <div class="panel-heading"> <h3 class="panel-title">命令</h3> </div> <div class="panel-body"> <textarea class="form-control" id="cmd"></textarea> <button onclick="PostTask('cmd')" id="execute_but" class="btn btn-info pull-right">执行</button> <button class="btn btn-danger" onclick="End()">终止</button> </div> </div> {% include 'components/taskresult.html' %} </div> <script> {% include 'components/post_task.js.html' %} </script> {% endblock %}
3、include 组件嵌套
3.1.把多个模板共用的css或者JavaScript代码集成到1个组件,变成公共组件,让其他模板通过{% include xxx %} 直接引入进来使用即可;(提高代码重用性)
{% load simple-fifter %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <h2>simple-fifter</h2> {% for iteam in userinfo %} {{ iteam|my_upper:'666' }} {% endfor %} <h2>simple-tag</h2> {%my_join userinfo '666' '888' %} {% include 'public.html' %} {% include 'public.html' %} {% include 'public.html' %} {% include 'public.html' %} {% include 'public.html' %} {% include 'public.html' %} {% include 'public.html' %} {% include 'public.html' %} </body> </html>
3.2.多层嵌套的include组件
在inculde组件里还可以继续嵌套include组件,这样可以使你的模板代码变得更加简洁、灵活、易于扩展。
{% extends "arya/layout.html" %} {% block out_css %} <link rel="stylesheet" href="/static/date/bootstrap-datetimepicker.min.css"> {% endblock %} {% block out_js %} <script src="/static/date/moment.js"></script> <script src="/static/date/bootstrap-datetimepicker.min.js"></script> {% endblock %} {% block content %} <div class="col-md-12"> {% if task_log_id %} {% include 'components/task_log.html' %} {% else %} {% include 'components/log_seach.html' %} {% endif %} </div> {% endblock %} {% block in_js %} <script> $('[name="q"]').hide(); $('[value="搜索"]').hide(); </script> {% endblock %}
<a href="/multitask/task/" class="btn btn-primary btn-sm">返回</a> <table class="table table-condensed table-responsive" style="color: white"> <thead> <tr> <th>执行时间</th> <th>任务</th> <th>状态</th> </tr> </thead> <tbody> {% for obj in task_list %} <tr> <td>{{ obj.date }}</td> <td>{{ obj.result }}</td> {% if obj.status == 0 %} <td>成功</td> {% elif obj.status == 3 %} <td>超时</td> {% endif %} </tr> {% endfor %} </tbody> </table> {% include 'components/task_log_page.html' %}
<nav aria-label="Page navigation" style="position: fixed;bottom: 5px;right: 50%"> <ul class="pagination"> {% if task_list.has_previous %} <li><a href="/multitask/log/{{ task_log_id }}/?page={{ task_list.previous_page_number }}">上页 <span class="sr-only">(current)</span></a></li> {% else %} <li class="disabled"><a href="#">上页</a></li> {% endif %} {% for page in p.page_range %} <li><a href="/multitask/log/{{ task_log_id }}/?page={{ page }}">{{ page }} <span class="sr-only">(current)</span></a></li> {% endfor %} {% if task_list.has_next %} <li><a href="/multitask/log/{{ task_log_id }}/?page={{ task_list.next_page_number }}">下页 <span class="sr-only">(current)</span></a></li> {% else %} <li class="disabled"><a href="#">下页</a></li> {% endif %} </ul> </nav>
-------------------------------------------------------------------
<form action=""method="post"> {% csrf_token %} <input id="start" type="text" name="start"> <input id="end" type="text" name="end"> <input type="submit" class="btn-info" value="搜素"> </form> <script> $("#start").datetimepicker({ format: 'YYYY年MM月DD日HH时mm分ss秒', locale: moment.locale('zh-CN') }); $("#start").datetimepicker({ format: 'YYYY-MM-DD', locale: moment.locale('zh-cn'), defaultDate: "1990-1-1" }); $("#end").datetimepicker({ format: 'YYYY年MM月DD日HH时mm分ss秒', locale: moment.locale('zh-CN') }); $("#end").datetimepicker({ format: 'YYYY-MM-DD', locale: moment.locale('zh-cn'), defaultDate: "1990-1-1" }); </script> {% include 'components/task.html' %} {% include 'components/task_page.html' %}
<table class="table table-responsive" style="color: white"> <thead> <tr> <th>序号</th> <th>执行时间</th> <th>任务类型</th> <th>任务概览</th> <th>操作</th> </tr> </thead> <tbody> {% for obj in task_list %} <tr> <td>{{ forloop.counter0 }}</td> <td>{{ obj.date }}</td> {% if obj.task_type == 0 %} <td>cmd</td> {% else %} <td>file_transfer</td> {% endif %} <td>{{ obj.content }}</td> <td><a href='/multitask/log/{{ obj.pk }}/' class='btn btn-primary btn-sm button'>详细</a></td> </tr> {% endfor %} </tbody> </table>
<nav aria-label="Page navigation" style="position: fixed;bottom: 5px;right: 50%"> <ul class="pagination"> {% if task_list.has_previous %} <li><a href="/multitask/task/?page={{ task_list.previous_page_number }}">上页 <span class="sr-only">(current)</span></a></li> {% else %} <li class="disabled"><a href="#">上页</a></li> {% endif %} {% for page in p.page_range %} <li><a href="/multitask/task/?page={{ page }}">{{ page }} <span class="sr-only">(current)</span></a></li> {% endfor %} {% if task_list.has_next %} <li><a href="/multitask/task/?page={{ task_list.next_page_number }}">下页 <span class="sr-only">(current)</span></a></li> {% else %} <li class="disabled"><a href="#">下页</a></li> {% endif %} </ul> </nav>
二龙湖浩哥:http://www.cnblogs.com/yuanchenqi/articles/6811632.html#3763280