Django之模板引擎(母版)

Django之模板引擎(母版)

 母版:存放所有页面的基本信息,基本样式

 子班:继承母版

    自定义当前页面私有的样式信息

 母版的样式:

  {% block xxx(名称) %} xxxxxxx(数据) {% endblock %}

   例如:layout.html 是母版

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" />
    <link rel="stylesheet" href="/static/plugins/font-awesome-4.7.0/css/font-awesome.css" />
    <link rel="stylesheet" href="/static/css/commons.css" />
    {% block css %} {% endblock %}**** //这就是母版
    <style>
        body{
            margin: 0;
        }
        .pg-header{
            height: 48px;
            min-width: 900px;
            background-color: #2b669a;
        }
    </style>
</head>
<body>
    <div class="pg-header">
        <div class="logo left">学员后台管理</div>
        <div class="avatar right" style="position: relative">
            <img style="width: 40px;height: 40px;" src="/static/images/1.jpg">
            <div class="user-info">
                <a>个人资料</a>
                <a>注销</a>
            </div>
        </div>
        <div class="rmenus right">
            <a><i class="fa fa-commenting-o" aria-hidden="true"></i> 消息</a>
            <a><i class="fa fa-envelope-o" aria-hidden="true"></i> 邮件</a>
        </div>
    </div>
    <div class="pg-body">
        <div class="menus">
            <a><i class="fa fa-futbol-o" aria-hidden="true"></i>班级管理</a>
            <a href="/students/">学生管理</a>
            <a>老师管理</a>
            <a>老师任课班级管理</a>
        </div>
        <div class="content">
            <ol class="breadcrumb">
              <li><a href="#">首页</a></li>
              <li><a href="/classes/">班级管理</a></li>
              <li class="active">添加班级</li>
            </ol>
            {% block way  %} {% endblock %} ****//这就是母版,
        </div>
    </div>
    {% block js %} {% endblock %} ****//这就是母版
</body>
</html>
View Code

 子版的样式:

  {% extends ‘xxx.html’ %}   继承xxx.html中的样式,xxx.html就是母版的样式

   例如:classes.html 就是套用里母版

{% extends "layout.html"%} //继承母版

{% block css %}  //这是写子版自己的样式 
    <style>
        .hide{
            display: none;
        }
        .shadow{
            position: fixed;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            background-color: black;
            opacity: 0.4;
            z-index: 999;
        }
        .addModal11{
            z-index: 1000;
            position: fixed;
            left: 50%;
            top: 50%;
            height: 300px;
            width: 400px;
            background-color: white;
            margin-left: -200px;
            margin-top: -150px;
        }
    </style>
{% endblock %}

{% block way %} //这是套用母版样式的地方,显示自己样式的数据
    <div>
        <div style="margin: 15px 0;">
            <a class="btn btn-primary" href="/add_class/">添加</a>
            <a class="btn btn-primary" onclick="showModal();">对话框添加</a>
            <a class="btn btn-primary" href="/index/">返回</a>
        </div>
        <table class="table table-striped table-bordered table-hover">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>班级名称</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                {% for item in class_lsit %}
                    <tr>
                        <td>{{ item.nid }}</td>
                        <td>{{ item.title }}</td>
                        <td>
                            <a class="glyphicon glyphicon-trash" href="/del_class/?nid={{ item.nid }}"></a>
                            |
                            <a class="fa fa-edit" onclick="modelEdit(this);"></a>
                            |
                            <a class="glyphicon glyphicon-pencil" href="/edit_class/?nid={{ item.nid }}"></a>
                        </td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
        <div id="shadow" class="shadow hide"></div>

        <div id="modal" class="addModal11 hide">
            <p>添加班级:<input id="title" type="text" name="title" placeholder="班级名称"></p>
            <input type="button" value="submit" onclick="AjaxSend();"/>
            <input type="button" value="cancel" onclick="cancleModal();"/><span id="errormsg"></span>
        </div>

        <div id="editModel" class="addModal11 hide">
            <h3>编辑框</h3>
            <p>
                <input id="editId" type="text" name="nid" style=" display: none" />
                <input id="editTitle" type="text" name="title" />
            </p>
            <input type="button" value="submit" onclick="editAjaxSend();" /><span id="errormsg"></span>
            <input type="button" value="cancel" onclick="cancleModal();" />
        </div>

        <script src="/static/jquery-1.12.4.js"></script>

        <script>
            function showModal() {
                document.getElementById("shadow").classList.remove("hide");   //找到遮罩层,并去挑遮罩层
                document.getElementById("modal").classList.remove("hide");
            }

            function cancleModal() {
                document.getElementById('shadow').classList.add('hide');
                document.getElementById('modal').classList.add('hide');
                document.getElementById('editModel').classList.add('hide');
            }

            function AjaxSend(){
                $.ajax({
                    url:'/modal_add_classes_ajax/',   //往哪里提交
                    type:'POST',                      //以什么方式提交
                    data:{"title":$("#title").val()},  //拿到全段输入的值
                    success:function (data) {
                        //当服务端处理完成后,返回数据时,该函数自动调用
                        //data是服务端返回的值
                        console.log(data);
                        if(data=="ok"){
                            location.href='/classes/'; //指定提交成功后跳转到哪里
                        }else {
                            $('#errormsg').text(data);
                        }
                    }
                })
            }

            function modelEdit(ths) {
                document.getElementById("shadow").classList.remove("hide");   //找到遮罩层,并去挑遮罩层
                document.getElementById("editModel").classList.remove("hide");
                /*
                1、获取当前点击标签
                2、获取当前标签的父标签,再找其上方标签
                3、获取当前行班级名称,赋值到编辑对话框中
                */
                var row = $(ths).parent().prevAll()   //$(ths)是获取当前标签。  .parent是当前父标签。  .prevAll是当前级标签的上面所有的标签。
                console.log(row);
                var content = $(row[0]).text();        //用列表取值的方式获取title。 .text是转成文本信息。
                $('#editTitle').val(content);           //找到title给他赋值给val里。

                var contentId = $(row[1]).text();
                $('#editId').val(contentId);
            }

            function editAjaxSend() {
                var nid = $('#editId').val();      //提交操作里前端获取id
                var content = $('#editTitle').val();     // 提交操作,前端获取新输入的值
                console.log(nid,content);
                $.ajax({
                    url:'/modal_edit_classes_ajax/',
                    type:"POST",
                    data:{"nid":nid,"content":content},
                    success:function (arg) {
                        // arg字符串类型
                        // JSON.parse(字符串) => 对象
                        // JSON.stringify(对象) => 字符串
                        arg = JSON.parse(arg);
                        if(arg.status){
                            //location.href="/classes/"     //这个是跳转
                            location.reload();      //这个是刷新
                        }else{
                            alert(arg.message);
                        }
                    }
                })
            }

        </script>
    </div>
{% endblock %} 
View Code

 

 在母版中有 {% block xxx(名称) %} xxxxxxx(数据) {% endblock %}

   在子版中的block中的数据会去替换母版的数据,但是母版的格式依旧。

   黄标为母版,这个编辑页面的样式,继承母版。

   绿和红标,为继承的代码块

 

模板补充:

  在后端传输字典类型的数据时,前端如何分别拿取key和value。

def test11111111(request):
    return render(request,"test11111.html",{
        "userinfo":{"k1":"v1","k2":"v2"}
    })

  方式1:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>打印字典所有的key</h2>
    {% for item in userinfo.values %}
        <h6>{{ item }}</h6>
    {% endfor %}

</body>
</html>

  方式1的结果: 

  方式2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>打印字典所有的key</h2>
    {% for k,v in userinfo.items %}
        <h6>{{ k }}---{{ v }}</h6>
    {% endfor %}
</body>
</html>

  方式2的结果:

  如果给前端传一些值改如何:

def test11111111(request):
    return render(request,"test11111.html",{"name":"george"})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>打印字典所有的key</h2>
    {{ name }}
</body>
</html>

  结果:

  但如果想要george变大写改如何操作呢?方式有两种:

  其一:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>打印字典所有的key</h2>
    {{ name|upper }}
</body>
</html>

这个upper的本质是一个带装饰器的函数.

  他是拿到一个value,并将value.upper操作的。而这个value就是我们后端传的name。

  其二:自定义模板函数 simple_filter 

    这个simple_filter的创建一个分为三步。

    a:在app中创建templatetags模块

    b:创建一个任意的py文件,比如:xx.py,并存放我们要用的自定义函数

from django import template

register = template.Library() # 这个别名必须叫register

@register.filter
def my_upper(value):
    return value.upper()

    c:在HTML的文件顶部加上 {% load xx %}   xx是在templatetags里创建的py文件。

{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>打印字典所有的key</h2>
    {{ name|my_upper }}
</body>
</html>

  针对第二步的py文件,是可以丰富其功能的。

  加参数:filter只支持两个参数,并且只支持前后各一个的。再多就不行啦。

from django import template

register = template.Library() # 这个别名必须叫register

@register.filter
def my_upper(value,arg):
    return value + arg
{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>打印字典所有的key</h2>
    {{ name|my_upper:"666" }}  // my_upper 后加冒号之后的就是第二个的参数,注意:冒号后不能有空格。
</body>
</html>

   tag的用法:

from django import template

register = template.Library() # 这个别名必须叫register

@register.filter
def my_upper(value,arg):
    return value + arg

@register.simple_tag()
def my_lower(value):
    return value.lower()

 

{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>打印字典所有的key</h2>
    <h3>filter</h3>
    {{ name|my_upper:"666" }}
    <h3>tag</h3>
    {% my_lower "GEORGE" %}   // my_lower 后有一个空格在
</body>
</html>

  加多个参数:

from django import template

register = template.Library() # 这个别名必须叫register

@register.filter
def my_upper(value,arg):
    return value + arg

@register.simple_tag()
def my_lower(value,a1,a2,a3):
    return value + a1 + a2 + a3
{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>打印字典所有的key</h2>
    <h3>filter</h3>
    {{ name|my_upper:"666" }}
    <h3>tag</h3>
    {% my_lower "GEORGE" "--" "N" "B" %}
</body>
</html>

  但是filter在参数上不如tag,可是filter可以用if判断,filter可以作为条件语句,放在if后面。而tag就不行。 

from django import template

register = template.Library() # 这个别名必须叫register

@register.filter
def my_upper(value,arg):
    return value + arg

@register.simple_tag()
def my_lower(value,a1,a2,a3):
    return value + a1 + a2 + a3

@register.filter
def my_bool(value):
    return False
{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>打印字典所有的key</h2>
    <h3>filter</h3>
    {{ name|my_upper:"666" }}
    
    {% if name|my_bool %}
        <h6>真</h6>
    {% else %}
        <h6>假</h6>
    {% endif %}

    <h3>tag</h3>
    {% my_lower "GEORGE" "--" "N" "B" %}
</body>
</html>

 

   在模板中也有include的概念:

    在模板中的include的就是导入组件的功能。

    在购物或社交的网址中,会有一些类似广告位的连接,以图片或图标的形式展示,他的位置固定,但内容可变。 

    include的小组件可以一个页面导入多个。

  在template里创建一个pub.html。

<div>
<h3>特别漂亮的组件</h3> <div class="title">标题</div> <div class="content">内容</div> </div>

  在目标页面加:

{% load xx %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% include "pub.html" %}
    {% include "pub.html" %}
    {% include "pub.html" %}
    <h2>打印字典所有的key</h2>
    <h3>filter</h3>
    {{ name|my_upper:"666" }}

    {% if name|my_bool %}
        <h6>真</h6>
    {% else %}
        <h6>假</h6>
    {% endif %}


    <h3>tag</h3>
    {% my_lower "GEORGE" "--" "N" "B" %}
</body>
</html>

   结果,这个include可以加多个。

  如果在pub.html的页面里,也可以拿后端传的的参数。

<div>
    <div class="title">标题:{{ name }}</div>
    <div class="content">内容:{{ name }}</div>
</div>

  这个name就是后端return的name的值。将pub用include的方式加到目标页面,就可以显示了。

 

------- END -------

posted @ 2018-03-01 16:47  王先生是胖子  阅读(245)  评论(0编辑  收藏  举报