zoukankan      html  css  js  c++  java
  • django之模板层

    什么是模板层

    模板层是在视图函数中被用作渲染的html文件,后端中的数据常常需要动态的传递到前端中。后端我们使用的python语法,而前端使用的是html语言。我们知道想让前端数据传递到后端,只需将数据在GET或者POST中携带。那后端如何将数据传递到前端呢?

    我们在视图层可以将HttpResponse或者JsonResponse直接将数据进行返回,但这不能满足前端胡里花哨的页面显示。

    有没有可能先制作好html文件,然后在其中预留一些位置,我们后端再将数据填入这些空白中呢?

    答案是肯定的。这就是django中的模板层,当然我们得遵循模板层特有的语法。

    1.模板语法符号

    {{ }}:变量相关

    {% %}:逻辑相关

    python基本数据类型全部支持传递给html文件。

    views.py
    -------------------
    def index(request):
        my_dict = {
            'user': 'yyh',
            'password': 123,
            'age': 18
        }
        return render(request, 'index.html', {'my_dict': my_dict})
    	# return render(request,'index.html',locals()) locals()会将函数命名空间内的所有变量名全部传递到index.html中
    
    index.html
    -------------------------------
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    </head>
    <body>
    <p>{{ my_dict }}</p>
    <p>{{ my_dict.user }}</p>
    <p>{{ my_dict.password }}</p>
    {% for key in my_dict %}
        {{ key }}
        {{ my_dict.key }}
    {% endfor %}
        
    {% for key,value in my_dict.items %}
        {{ key }}
        {{ value }}
    {% endfor %}
    <br>
    {{ my_dict.hobbies.1.1 }}
        
    {# my_dict.values my_dict.items #}
    </body>
    </html>
    

    可以看到只能模板语法不管是列表还是字典都只能通过 . 的方式取值。

    2.模板语法之过滤器

    |length
    |add
    |default
    |truncatechars
    |truncatewords
    |filesizeformat
    |slice
    |date
    |safe
    
    <p>过滤器  |左边的会当做过滤器的第一个参数 过滤器名右边的会当做过滤器的第二个参数</p>
    <p>求数据长度:{{ s|length }}</p>
    <p>加法运算:{{ n|add:10 }}、{{ s|add:13132 }}、{{ s|add:'DSB' }}</p>
    <p>默认值(判断值是否为空):{{ b|default:'这个b布尔值是True' }}、{{ ff|default:'这个ff布尔值是Flase' }}</p>
    <p>截取字符(截取5个字符 三个点也算):{{ s|truncatechars:8 }}</p>
    <p>截取单词(截取8个单词 三个点不算):{{ ss|truncatewords:8 }}、{{ sss|truncatewords:4 }}</p>
    <p>文件大小:{{ file_size|filesizeformat }}</p>
    <p>切片操作:{{ s|slice:'0:2' }}、{{ s|slice:"0:8:2" }}</p>
    <p>日期格式化:{{ ddd|date:'Y年/m月/d日' }}</p>
    <p>转义:{{ res|safe }}、{{ res1 }}、后端直接标识安全:{{ res2 }}</p>
    

    3.前后端取消转义

    后端
    ----------
    def login(request):
        s = '<h1>hello world</h1>'
        return render(request,'login.html',locals())
    
    前端
    -------
    <body>
    {{ s }}
    </body>
    ---------# 浏览器将显示'<h1>hello world</h1>'
    
    ----------
    <body>
    {{ s|safe }}
    </body>
    ----------   # 浏览器将以h1渲染helloworld
    

    取消转义可以在前端完成,也可以在后端完成

    from django.utils.safestring import mark_safe
    def login(request):
        s = '<h1>hello world</h1>'
        s = mark_safe(s)
        return render(request, 'login.html', locals())
    
    
    ----------------
    <body>
    {{ s }}
    </body>
    

    4.模板语法之标签

    {% for foo in l %}
        <p>{{ forloop }}</p>
    {% endfor %}
    
    
    {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 6, 'revcounter0': 5, 'first': True, 'last': False}
    
    {'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 5, 'revcounter0': 4, 'first': False, 'last': False}
    
    {'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 4, 'revcounter0': 3, 'first': False, 'last': False}
    
    {'parentloop': {}, 'counter0': 3, 'counter': 4, 'revcounter': 3, 'revcounter0': 2, 'first': False, 'last': False}
    
    {'parentloop': {}, 'counter0': 4, 'counter': 5, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False}
    
    {'parentloop': {}, 'counter0': 5, 'counter': 6, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
    

    模板语法中的for循环自带有一个forloop的对象,可以通过使用这个对象对for循环进行一些处理。

    {% for foo in l %}
        {% if forloop.first %}
            <p>第一次循环噢</p>
        {% elif forloop.last %}
            <p>最后一次循环哦</p>
        {% else %}
            <p>{{ foo }}</p>
        {% endif %}
    {#    在l为空时执行#}
        {% empty %}
        <p>haa</p>
        <p>haa</p>
    {% endfor %}
    
    # 可用add来判断第几次循环
    {% for foo in l %}
        {% if forloop.counter|add:-2 %}
            {{ foo }}
        {% endif %}
    {#    在l为空时执行#}
        {% empty %}
        <p>haa</p>
    {% endfor %}
    </body>
    </html>
    

    5.自定义过滤器

    自定义过滤器 标签 inclusion_tag
    先完成以下前期准备工作
    1.在应用名下新建一个名字必须叫templatetags文件夹
    2.在该文件夹内新建一个任意名称的py文件(eg:mytag)
    3.在该文件内 必须先写以下两句代码
    from django.template import Library
    
    register = Library()
    
    # 自定义过滤器
    @register.filter(name='my_sum')
    def index(a,b):
        return a + b
    
    
    # 自定义标签
    @register.simple_tag(name='my_baby')
    def xxx(a,b,c,d):
        return '%s?%s?%s?%s'%(a,b,c,d)
    
    
    # 自定义inclusion_tag
    @register.inclusion_tag('demo.html',name='myin')
    def index1(n):
        l = []
        for i in range(n):
            l.append(i)
            # 将列表传递给demo.html
            # return locals()
            return {'l':l}
    
    <p>自定义过滤器的使用</p>
    {% load mytag %}
    <p>{{ 10|my_sum:90 }}</p>
    
    <p>自定义标签的使用</p>
    {% load mytag %}
    <p>{% my_baby 1 2 3 'hello world' %}</p>
    
    
    <p>自定义的过滤器可以在逻辑语句中而自定义的标签不可以</p>
    {% if 10|my_sum:100 %}
    <p>条件成立</p>
    {% endif %}
    
    {% if my_baby 1 2 3 4 %}
    <p>条件成立</p>
    {% endif %}
    
    <p>自定义inclusion_tag的使用</p>
    {% load mytag %}
    {% myin 5 %}
    # 总结 页面上使用他们 统一先导入
    {% load mytag %}
    

    6.模板的继承

    模板的继承实际上是在一个html模版上用 {% block 名字%}{% endblock %}

    来划分一块区域。其他的html模板可以通过{% extends 'index.html' %},然后

    {% block 名字%}{% endblock %}可以继承index.html里的代码,并将自己的block填充。{{block.super}}可以调用父页面对应区域的内容(在哪个block下使用就调用哪一块)

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
        <link href="/static/bootstrap-3.3.7-dist/css/bootstrap.css" rel="stylesheet">
        <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
        {% block css %}
    
        {% endblock %}
    </head>
    <body>
    {# 导航条样式 #}
    <nav class="navbar navbar-inverse">
      <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Brand</a>
        </div>
    
        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
            <li><a href="#">Link</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li><a href="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">Separated link</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">One more separated link</a></li>
              </ul>
            </li>
          </ul>
          <form class="navbar-form navbar-left">
            <div class="form-group">
              <input type="text" class="form-control" placeholder="Search">
            </div>
            <button type="submit" class="btn btn-default">Submit</button>
          </form>
          <ul class="nav navbar-nav navbar-right">
            <li><a href="#">Link</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li><a href="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">Separated link</a></li>
              </ul>
            </li>
          </ul>
        </div><!-- /.navbar-collapse -->
      </div><!-- /.container-fluid -->
    </nav>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-3">
                <div class="list-group">
                     {% block list_style %}
                      <a href="/index/" class="list-group-item active" id="id_index">
                        首页
                      </a>
                      <a href="/login/" class="list-group-item" id="id_login">登录</a>
                      <a href="/register/" class="list-group-item" id="id_register">注册</a>
                     {% endblock %}
                </div>
            </div>
            <div class="col-md-9">
                <div class="panel panel-default">
                  <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                  </div>
                  <div class="panel-body panel-primary">
                      {% block content %}
    
                      {% endblock %}
    {#                <div class="jumbotron">#}
    {#                  <h1>Hello, world!</h1>#}
    {#                  <p>...</p>#}
    {#                  <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>#}
    {#                </div>#}
                  </div>
                </div>
            </div>
        </div>
    </div>
    {% block js %}
        <script>
            $('#id_index').addClass('active').siblings().removeClass('active')
        </script>
    {% endblock %}
    </body>
    </html>
    

    login.html

    {% extends 'index.html' %}
    {#{% block list_style %}#}
    {#<a href="/index/" class="list-group-item">#}
    {#首页#}
    {#</a>#}
    {#<a href="/login/" class="list-group-item active">登录</a>#}
    {#<a href="/register/" class="list-group-item">注册</a>#}
    {#{% endblock %}#}
    
    {% block css %}
        <style>
    
        </style>
    {% endblock %}
    
    
    {% block content %}
        <h1 class="text-center">登录</h1>
        <p>用户名:<input type="text"></p>
        <p>密码:<input type="password"></p>
        <button class="btn btn-danger">提交</button>
    {% endblock %}
    
    {% block js %}
        <script>
            $('#id_login').addClass('active').siblings().removeClass('active')
        </script>
    {% endblock %}
    

    7.模板的导入

    django还支持将html页面当做模块使用,哪里需要导哪里,被导入的这个html文件通常是不完整的。

    {% include 'left.html' %}

  • 相关阅读:
    WCF系列(一)BasicHttpBinding 和 WsHttpBinding 的不同点
    SQL Server中的事务与锁
    领域驱动设计之领域模型
    http请求到响应经历的阶段
    vs调试
    c# 基本值类型及其默认值
    ASP.NET中JSONP的两种实现以及其他跨域解决方案的简单实现
    通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
    最完整的数据倾斜解决方案(spark)
    Spark性能调优
  • 原文地址:https://www.cnblogs.com/Ghostant/p/12163684.html
Copyright © 2011-2022 走看看