Django的模板系统和模板的继承

模板系统

语法

变量相关的

{{ name }}    这个是从views视图传过来的变量

下面这个就是我们视图传入的是一个列表,下标取值

{{ name_list.0 }}

{{ name_list.1 }}

{{ name_list.2 }}

如果传入的是字典那么:

{{ name_dict.name }}

视图中传入的是字典列表元组等数据,把python中使用"[]"取值变为点"."取值

 

常用的内置filter

{{ file_size|filesizeformat }}   file_size表示的是视图里面传过来的文件大小单位为B的转换为合适的单位

{{ name_list|slice:"1:-1" }}   相当于切片,这个nam_list要能够支持切片

{{ now|date:"Y-m-d H:i:s" }}  事件格式化,传过来的要是一个时间的对象

{{ a_html|safe }} 前面传过来的是一个html格式的字符串如果不加上safe就代表是一个字符串前面不会把它当做标签什么的来处理,加上这个就可以翻译成标签来使用。不可以随便使用

{{ p_str|truncatechars:20 }}  截取传过来的字符串前面20个字符

{{ name|length }} 这个就是求前面变量的长度

{{ bucunzai|default:"这个变量并没有传值,使用的是默认值" }}

 

自定义filter

1. 定义阶段
  1. 在app下面新建一个python的包:templatetags
  2. 在上面的Python包中新建一个Python文件,名字随意
  3. 在上述python文件中:
    from django import template

    # 生成一个注册用的实例
    register = template.Library()
    # 定义并注册一个自定义的filter函数
    @register.filter(name='addsb')
    def add_sb(arg):
    return "{} sb".format(arg)
2. 调用阶段:
  1. 在Django的模板文件中,导入刚才新建的python文件
  {% load py文件名 %}
  2. 按照filter的语法调用
  {{ name|addsb }}

3、 自定义的simple_tag
  比filter高级一点点
  它可以接受的参数个数大于2

5. 自定义的inclusion_tag
  用来返回一段html代码(示例:返回ul标签)

1. 定义阶段
  在app下面新建templatetags 文件夹(注意是Python包)
  新建一个py文件

  from django import template
  # 生成注册示例,名字必须是register
  register = template.Library()
  @register.inclusion_tag("ul.html")
  def show_ul(num):
  num = 1 if num < 1 else int(num)
  data = ["第{:0>3}号技师".format(i) for i in range(1, num+1)]
  return {"data": data}

2. 调用阶段
  {% load xx %}
  {% show_ul 10 %}

逻辑相关

1、if判断

{% if a > b %}
{% endif %}

{% if a > b %}
{% else %}
{% endif %}

{% if a > b %}
{% elif %}
{% else %}
{% endif %}

2、for 循环

  1. for循环的基本用法:
    {% for i in name_list %}
    {{ i }}
    {% endfor %}
  
    {% for i in name_list %}
      {{ i }}
    {% empty %}
      空空如也
    {% endfor %}

    这个就是当我们传过来的数据为空的时候,执行empty里面的内容。比如我们查找数据库所有关于这个作者的书籍,那么该作者没有书籍我们页面上就会显示空空如叶

  2. for循环可用的属性:

    当列表为空或者非空时执行不同操作:

{% for item in list %}
    ...
{% empty %}
    ...
{% endfor %}

使用forloop.counter访问循环的次数,下面这段代码依次输出循环的次数,从1开始计数:

{% for item in list %}
    ...
    {{ forloop.counter }}
    ...
{% endfor %}

 

从0开始计数:

{% for item in list %}
    ...
    {{ forloop.counter0 }}
    ...
{% endfor %}

 

判断是否是第一次循环:

复制代码
{% for item in list %}
    ...
    {% if forloop.first %}
        This is the first round. 
    {% endif %}
    ...
{% endfor %}
复制代码

 

判断是否是最后一次循环:

复制代码
{% for item in list %}
    ...
    {% if forloop.last %}
        This is the last round.
    {% endif %}
    ...
{% endfor %}
复制代码

 

逆向循环:

{% for item in list reversed %}
    {{ item }}
{% endfor %}

    这里面得forloop是固定的不可更改
    forloop.counter      计数从1开始   (1、2、3、4、5、6)
    forloop.counter0    计数从0开始   (0、1、2、3、4、5)
    forloop.revcounter  反过来计数1    (6、5、4、3、2、1)
    forloop.revcounter0     反过来计数最后一位是0 (5、4、3、2、1、0)

    forloop.first                   循环的第一个数
    forloop.last                   循环的最后一个

    forloop.parentloop --> 两层for循环,内层循环引用外层循环

母版和继承

1. 什么时候用母版?

html页面有重复的代码,把它们提取出来放到一个单独的html文件。
(比如:导航条和左侧菜单)

2. 具体使用的步骤:
1. 把公用的HTML部分提取出来,放到base.html文件中
2. 在base.html中,通过定义block,把每个页面不同的部分区分出来
3. 在具体的页面中,先继承母版
4. 然后block名去指定替换母版中相应的位置

3. 使用母版和继承的注意事项:
1. {% extends 'base.html' %} --> 母版文件:base.html要加引号
2. {% extends 'base.html' %}必须放在子页面的第一行!!!
3. 可以在base.html中定义很多block,通常我们会额外定义page-css和page-js两个块
4. view.py相应的函数中返回的是对应的子页面文件 不是不是不是 base.html

<!DOCTYPE html>
<!-- saved from url=(0042)https://v3.bootcss.com/examples/dashboard/ -->
<html lang="zh-CN">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="https://v3.bootcss.com/favicon.ico">

    <title>BMS-图书管理系统</title>
    <!-- Bootstrap core CSS --><link href="{% static 'bootstrap/css/bootstrap.min.css'%}" rel="stylesheet">


    <!-- Custom styles for this template -->
    <link href="{% static 'dashboard.css'%}" rel="stylesheet">
    <link rel="stylesheet" href="{% static 'fontawesome/css/font-awesome.min.css'%}">

    {% block page-css %}

    {% endblock %}
</head>

<body>

{% include 'xiaohei.html' %}

<div class="container-fluid">
    <div class="row">
        <div class="col-sm-3 col-md-2 sidebar">
            <ul class="nav nav-sidebar">
                <li class="{% block publisher_class %}{% endblock %}"><a href="/publisher_list/">出版社列表页</a></li>
                <li class="{% block book_class %}{% endblock %}"><a href="/book_list/">书籍列表</a></li>
                <li class="{% block author_class %}{% endblock %}"><a href="/author_list/">作者列表</a></li>
            </ul>

        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            {# 这里是每个页面不同的部分 #}
            {% block page-main %}

            {% endblock %}
        </div>
    </div>
</div>


<div class="modal fade" tabindex="-1" role="dialog" id="myModal">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">用户信息</h4>
            </div>
            <div class="modal-body">
                <form class="form-horizontal">
                    <div class="form-group">
                        <label for="inputEmail3" class="col-sm-2 control-label">邮箱</label>
                        <div class="col-sm-10">
                            <input type="email" class="form-control" id="inputEmail3" placeholder="Email">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">密码</label>
                        <div class="col-sm-10">
                            <input type="password" class="form-control" id="inputPassword3" placeholder="Password">
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                <button type="button" class="btn btn-primary">保存</button>
            </div>
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="{% static 'jquery-3.3.1.js'%}"></script>
<script src="{% static 'bootstrap/js/bootstrap.min.js'%}"></script>
{% block page-js %}

{% endblock %}
</body>
</html>

 上面黄色部分就是我们在母模板中定义的block并且起了名字这个地方就是在具体模板中替换的位置,然后就是在具体模板中先先继承模板在,然后block名去指定替换母版中相应的位置

具体实现模板

{# 继承母版 #}
{% extends 'base.html' %}

{# 把自己页面的内容 塞到母版里面相应的位置 #}
{% block page-main %}
   <h1 class="page-header">书籍管理页面</h1>
            <div class="panel panel-primary">
                <!-- Default panel contents -->
                <div class="panel-heading">书籍列表 <i class="fa fa-thumb-tack pull-right"></i></div>
                <div class="panel-body">
                    <div class="row" style="margin-bottom: 15px">
                        <div class="col-md-4">
                            <div class="input-group">
                                <input type="text" class="form-control" placeholder="Search for...">
                                <span class="input-group-btn">
                                    <button class="btn btn-default" type="button">搜索</button>
                                </span>
                            </div><!-- /input-group -->
                        </div><!-- /.col-md-4 -->
                        <div class="col-md-3 pull-right">
                            <a href="/add_book/" class="btn btn-success pull-right">新页面添加</a>
                            <button class="btn btn-success pull-right" data-toggle="modal" data-target="#myModal">新增</button>
                        </div>

                    </div><!-- /.row -->

                    <table class="table table-bordered">
                        <thead>
                        <tr>
                            <th>#</th>
                            <th>id</th>
                            <th>书名</th>
                            <th>出版社名称</th>
                            <th>操作</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for i in all_book %}
                            <tr>
                                <td>{{ forloop.counter }}</td>
                                <td>{{ i.id }}</td>
                                <td>{{ i.title }}</td>
                                <td>{{ i.publisher.name }}</td>
                                <td>
                                    <a class="btn btn-danger" href="/delete_book/?id={{ i.id }}">删除</a>
                                    <a class="btn btn-info" href="/edit_book/?id={{ i.id }}">编辑</a>
                                </td>
                            </tr>
                        {% empty %}
                            <tr>
                                <td colspan="5" class="text-center">暂时没有数据哦~</td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>

                    <nav aria-label="Page navigation" class="text-right">
                        <ul class="pagination">
                            <li>
                                <a href="#" aria-label="Previous">
                                    <span aria-hidden="true">&laquo;</span>
                                </a>
                            </li>
                            <li><a href="#">1</a></li>
                            <li><a href="#">2</a></li>
                            <li><a href="#">3</a></li>
                            <li><a href="#">4</a></li>
                            <li><a href="#">5</a></li>
                            <li>
                                <a href="#" aria-label="Next">
                                    <span aria-hidden="true">&raquo;</span>
                                </a>
                            </li>
                        </ul>
                    </nav>
                </div>

            </div>

{% endblock %}
{% block book_class %}
    active
{% endblock %}
{% block page-css %}
    {% load static %}
{#    <link rel="stylesheet" href="{% static 'book_list_only.css' %}">#}
    <link rel="stylesheet" href="{% get_static_prefix %}book_list_only.css">
{% endblock %}

母版里面定义block(块),子页面使用block(块)去替换母版中同名的块,可以替换也可以不替换。

2、组件

include

当有一些小的标签很多页面都需要用到的时候我们可以单独在一个html中将写标签,在tp1中以及tp2中通过include调用

如:{% include "插入的xxx.html标签名字" %}

这个可以在母模板中插入也可以在具体模板中使用

插入的模板一般都不是一个完整的html网页。

<form>

  <input type="text">

  <input type="text">

</form>

 类似上面的一个标签。

 

3、静态文件的灵活写法。

1. 利用Django模板语言内置的static方法帮我拼接静态文件的路径
  {% load static %}   导入static方法
  <link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
2. 利用内置的get_static_prefix获取静态文件路径的别名,我们自行拼接路径
  {% load static %}
  <link href="{% get_static_prefix %}bootstrap/css/bootstrap.min.css" rel=stylesheet>
3. as语法(一个路径多次用到,可以使用as保存到一个变量,后面就直接使用变量代替具体路径)相当于我们使用import

这样我们就不会因为setting里面static路径的改变而在每个文件中改变。

posted on 2018-07-17 12:14  与影前行  阅读(809)  评论(0编辑  收藏  举报

导航