zoukankan      html  css  js  c++  java
  • 🍖Django框架之模板层

    一.两种模板方法

    • 变量相关 : {{ }}

    • 逻辑相关 : {% %}

    二.注释

    • 注释是代码之母 : {# #}

    三.模板语法之传值

    1.Python中基本数据类型传值

    def test_func(request):
        s = "Hello 派大星!"
        i = 1314520
        f = 1.75
        l = [1,2,3,4,5]
        d = {"name":"shawn","age":23}
        t = (2,3,4,5,5)
        se = {3,4,5,'rr'}
        b = True
        
        # 传值方式一 : 使用字典的格式一个个传
        return render(request,'test.html',{'strs':s,'ints':i,'lists':l,...})
        # 传值方式二 : 使用 locals()将当前名称空间所有的变量名全部传递微页面
        return render(request,'test.html',locals())
    
    • test.html 文件
    <h1>{{ s }}</h1>
    <h1>{{ i }}</h1>
    <h1>{{ f }}</h1>
    <h1>{{ l }}</h1>
    <h1>{{ d }}</h1>
    <h1>{{ t }}</h1>
    <h1>{{ se }}</h1>
    <h1>{{ b }}</h1>
    

    image-20210318194630391

    2.函数与类的传递

    def test_func(request):
    
        def aa():
            print("aa--->")
            return 'I am aa'
    
        class Bar(object):
    
            def cc(self):
                print("Bar-->cc")
    
        B1 = Bar()
        return render(request, 'test.html', locals())
    
    • 模板层
    <h1>{{ aa }}</h1>
    <h1>{{ Bar }}</h1>
    <h1>{{ B1 }}</h1>
    

    image-20210318194502925

    3.函数名与类名注意点

    • 传递函数名与类名都会自动加括号调用
    • 传入函数名得到的结果是函数的返回值
    • 模板语法不支持额外的传参,也就是函数无法传参

    4.传值方式优缺点 :

    • 传值方式一 : 传值精确, 不会造成资源浪费
    • 传值方式二 : 传值简单, 可能造成一定的资源浪费

    四.模板语法之获取值

    • django模板语法取值只能采用句点符(.),也就是点

    • 可以根据索引以及键取值,支持多个很多个点........

    # views.py
    def test_func(request):
        ll = [1,2,{"name":"shawn","age":23,"hobby":["read","study"]}]
        return render(request,"test.html",{"ll":ll})
    
    # 想要取出爱好read
    # test.html
    <h1>{{ ll.2.hobby.0 }}</h1>
    

    image-20210318195629158

    五.模板语法之过滤器Filter

    1.过滤器说明

    • 类似于Python的内置方法
    • 将竖杠左侧的数据当做第一个参数传给右边的过滤器
    • 语法 : {{ [数据]|过滤器:可选参数 }}
    • 注意 : 竖杠左右两边没有空格
    • 过滤器参数包含空格的话需要使用引号包裹
    • 过滤器最多只能有两个参数

    2.常用过滤器使用

    • django中大约60中过滤器,下面只介绍常用过滤器
    # views.py
    def test_func(request):
        s = "Hello 派大星!"
        i = 1314520
        f = 1.75
        l = [1,2,3,4,5]
        d = {"name":"shawn","age":23}
        t = (2,3,4,5,5)
        se = {3,4,5,'rr'}
        b = True
        w = 'aa bb cc dd ee ff'
    
        return render(request,'test.html',locals())
    
    <!-- test.html-->
    <p>统计长度:{{ s|length }}</p>
    <!-- add数字相加,字符拼接-->
    <p>加法运算:{{ i|add:1000 }}</p>
    <p>字符串拼接:{{ s|add:'Hello 海绵宝宝' }}</p>
    <p>拼接:{{ s|join:'@' }}</p>
    <p>切片:{{ l|slice:'0:5:2' }}</p>
    <p>日期格式:{{ ctime|date:'Y年-m月-d日 H时:i分:s秒' }}</p>
    <!-- 如果第一个参数的布尔值是true则显示左边的值,否则显示default后的值-->
    <p>默认值:{{ b|default:'哈哈' }}</p>  
    <p>文件大小:{{ file_size|filesizeformat }}</p>
    <!-- 截取内容包含三个点,并且算在字符个数之内-->>
    <p>截取文本:{{ w|truncatechars:6 }}</p>
    <!-- 截取内容包含三个点,但不算在单词个数之内,单词识别是以空格来区分的-->
    <p>截取单词:{{ w|truncatewords:3 }}</p>
    

    image-20210326223226444

    3.转意

    • 后端使用转意
    from django.utils.safestring import mark_safe
    html_safe = mark_safe('<h1>你好</h1>')
    
    • 前端使用转意
    {{ html|safe }}
    

    六.模板语法之标签

    类似于Python中的流程控制

    1.for循环

    {% for i in l %}
        <p>{{ forloop }}</p>
        <p>{{ i }}</p>  # 循环从列表 l 中取出一个个元素
    {% endfor %}
    

    我们再看看 forloop 输出的是什么:

    image-20210318214321276

    2.if 判断

    # i = 90
    
    {% if i > 100 %}
        <p>is True</p>
    {% elif i > 80 %}
        <p>is two</p>
    {% else %}
        <p>is no</p>
    {% endif %}
    

    image-20210318215255704

    3.for 与 if 混合使用

    {% for i in l %}
        {% if forloop.first %}
            <p>is first</p>
        {% elif forloop.last %}
            <p>is last</p>
        {% else %}
            <p>{{ i }}</p>
        {% endif %}
    {% endfor %}
    

    image-20210318215606748

    4.empty : 空

    {% for foo in request %}
        {% empty %}
            <p>传入的数据为空,无法进行循环</p>
    {% endfor %}
    

    image-20210318215938511

    5.with : 取别名

    {% with ll.2.hobby.0 as hb %}
        <p>{{ hb }}</p>             # 可以使用别名取值
        <p>{{ ll.2.hobby.0 }}</p>   # 也可以使用原来的方式取值
    {% endwith %}
    

    image-20210318220320333

    6.字典values、keys、items方法

    {% for k in d.keys %}
        <p>{{ k }}</p>
    {% endfor %}
    
    {% for v in d.values %}
        <p>{{ v }}</p>
    {% endfor %}
    
    {% for kv in d.items %}
        <p>{{ kv }}</p>
    {% endfor %}
    

    七.自定义过滤器、标签、inclusion_tag

    类似于Python中的自定义函数

    1.创建 templatetags 文件

    • 首先在应用下创建一个名字必须叫"templatetags"文件夹
    • 在改文件夹下创建一个任意名称的 py 文件 (例 : mytag)
    • 在该 py 文件内固定书写两行代码
    from django import template
    register = template.Library()
    

    2.自定义过滤器

    • 自定义过滤器最多只能有两个形参
    from .templatetags.mytag import register
    
    # 在模板层导入自定义的过滤器时使用的是这里指定的名字
    @register.filter(name='myfilter')  
    def sums(a, b):   # 函数名随便起什么
        return a + b  # 返回两个参数的和
    
    {% load mytag %}  # 导入tag文件
    <p>{{ i|myfilter:100 }}</p>  # 使用myfilter过滤器
    

    image-20210318225017009

    3.自定义标签

    • 自定义标签可以有多个参数
    from .templatetags.mytag import register
    
    # 在模板层导入自定义的标签时使用的是这里指定的名字
    @register.simple_tag(name="my_tag")
    def my_join(a,b,c,d):          # 函数名任意
        return f'{a}/{b}/{c}/{d}'  # 返回参数拼接后的结果
    
    {% load mytag %}  # 导入tag文件
    <p>{% my_tag 'hello' 'pai' 'da' 'xing' %}</p>  # 标签之后的多个参数彼此之间用空格隔开
    

    image-20210318230441986

    • 示例二
    from .templatetags.mytag import register
    
    # 在模板层导入自定义的标签时使用的是这里指定的名字
    @register.simple_tag(name="my_tag")
    def my_join(a,b):          # 函数名任意
        return a+b             # 返回和
    
    {% load mytag %}
    <p>{% my_tag i 100 %}</p>
    

    image-20210318231336629

    4.自定义 inclusion_tag

    • inclusion_tag 的内部原理:
    • 在HTML页面中导入写好的 inclusion_tag 并调用了
    • 触发了py文件中一个函数的执行并产生结果
    • 产生的结果通过模板语法传递给一个HTML页面进行渲染
    • 渲染完毕后又返回调用 inclusion_tag 的位置
    • 示例
    from .templatetags.mytag import register
    
    @register.inclusion_tag('test.html',name='my_incl_tag')  # 第一个参数是需要渲染的HTML页面
    def func(n):
        data=[]
        for i in range(n):
            data.append(f'第{i}页')
        return locals()
    
    # test.html 文件
    {% load mytag %}
    <p>{% my_incl_tag 6 %}</p>
    
    # test2.html
    {{ data }}
    {% for foo in data %}
        {% if forloop.first %}
            <p>{{foo}}</p>
        {% elif forloop.last %}
            <p>{{ foo }}</p>
        {% else %}
            <p>{{ foo }}</p>
        {% endif %}
    {% endfor %}
    

    test.html 页面中调用了 inclusion_tag----->触发执行了一个函数产生结果并渲染到 test2.html 页面中, 渲染完又返回 test.html 页面

    image-20210318235133415

    八.模板的导入

    类似于后端的模块, 想要什么页面,局部直接导入即可

    {% include 'edit.html' %}  # 直接在当前HTML文件里面显示 edit.html 文件的内容
    

    九.模板的继承

    1.模板继承的使用

    • 模板的继承首先需要选择一个模板页面, 在该页面里面使用 block 划定可以被更改的区域
    # 母板页面 'home.html' 文件
    {% block [区域名称] %}
    ......
    {% endblock %}
    
    • 想要继承的页面可以使用 extends 来继承某一个页面
    # 子版
    {% extends 'home.html' %}
    {% block [区域名称] %}
    ......
    {% endblock %}
    

    子版继承了模板, 那么子版的整体格式与模板一样, 被 block 划分了的区域可以自己随意更改

    2.模板的三个区域

    • 母板在划分区域的时候一般有三个区域
    {% block css %}
        # css区域
    {% endblock %}
    
    {% block content %}
        # HTML区域
    {% endblock %}
    
    {% block js %}
        # js区域
    {% endblock %}
    

    目的是为了让子版具有独立的css、js等,增加扩展性

    • 子版也可以继续使用母版划定了区域内的内容
    {{ block.super }}
    

    3.示例

    • 路由层
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('home/', views.func),
        path('index/', views.func2,name='index_name'),
    ]
    
    • 视图层
    def func(request):
        return render(request,'home.html')
    
    def func2(request):
        return render(request,'index.html')
    
    • 模板层
    # home.html
    {% block left-body %}
    <div class="jumbotron">
        <h1>Hello, world!</h1>
        <p>这里是一个block划分的区域</p>
        <p><a class="btn btn-primary btn-lg" href="{% url 'index_name' %}" role="button">Learn more</a></p>
    </div>
    {% endblock %}
    
    # index.html
    {% extends 'home.html' %}
    {% block left-body %}
        <div class="row">
          <div class="col-xs-6 col-md-4 col-md-offset-2">
            <a href="#" class="thumbnail">
              <img src="../static/img/11.png" alt="...">
            </a>
          </div>
            <div class="col-xs-6 col-md-4 col-md-offset-2">
                <a href="#" class="thumbnail">
                  <img src="../static/img/11.png" alt="...">
                </a>
            </div>
        </div>
    {% endblock %}
    
    • home.html 页面

    image-20210319153623274

    • index.html 页面

    image-20210319153709598

    十.小练习

    1.需求

    • 增删改查功能

    • 將对用户增删改查的功能使用模板的继承来写

    • 代码除了模板层与之前无太大差别

    2.代码实现

    • urls.py 文件
    from django.contrib import admin
    from django.urls import path,re_path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('home/', views.home_func,name='home_name'),
        re_path('^edit/(d+)', views.edit_func,name='edit_name'),
        re_path('^del/(d+)', views.del_func,name='del_name'),
        path('insert/', views.insert_func,name='insert_name'),
    ]
    
    • views.py 文件
    def home_func(request):
        user_obj_list = models.User.objects.all()
        return render(request,'home.html',locals())
    
    def edit_func(request,id):
        if request.method == "POST":
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
            age = request.POST.get('age')
            models.User.objects.filter(id=id).update(name=name,pwd=pwd,age=age)
            return redirect('home_name')
        user_obj = models.User.objects.filter(id=id).first()
        return render(request,'edit.html',{'user_obj':user_obj})
    
    def del_func(request,id):
        models.User.objects.filter(id=id).delete()
        return redirect('home_name')
    
    def insert_func(request):
        if request.method == "POST":
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
            age = request.POST.get('age')
            models.User.objects.create(name=name,pwd=pwd,age=age)
            return redirect('home_name')
        return render(request,'insert.html')
    
    • 模板层文件
    # home.html 文件
    
    ##[导航栏代码]
    ##[左侧边栏代码]
    ##[右边内容由block划分]
    {% block left-body %}
        <div class="container">
            <div class="row">
                <h1 class="text-center">用户数据</h1>
                <div class="col-md-8 col-md-offset-2">
                    <table class="table table-hover table-striped">
                        <thead>
                        <tr>
                            <th>编号</th>
                            <th>姓名</th>
                            <th>密码</th>
                            <th>年龄</th>
                            <th>操作</th>
                        </tr>
                        </thead>
                        <tbody>
                            {% for user_obj in user_obj_list %}
                                <tr>
                                    <td>{{ user_obj.id }}</td>
                                    <td>{{ user_obj.name }}</td>
                                    <td>{{ user_obj.pwd }}</td>
                                    <td>{{ user_obj.age }}</td>
                                    <td>
                                        <a href="{% url 'del_name' user_obj.id %}">删除</a>
                                        <a href="{% url 'edit_name' user_obj.id %}">修改</a>
                                    </td>
                                </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                <div class="col-md-8 col-md-offset-2">
                    <form action="{% url 'insert_name' %}" method="get">
                        <input type="submit" class="btn btn-block btn-warning" value="新增">
                    </form>
                </div>
                </div>
            </div>
        </div>
    {% endblock %}
    
    
    # edit.html 文件
    
    {% extends 'home.html' %}
    {% block left-body %}
    <div class="container">
    <div class="row">
        <h2 class="text-center">修改数据</h2>
        <div class="col-md-8 col-md-offset-2">
            <form action="" method="post">
                username:
                <input type="text" name="name" class="form-control" value="{{ user_obj.name }}">
                password:
                <input type="text" name="pwd" class="form-control" value="{{ user_obj.pwd }}">
                age:
                <input type="number" name="age" class="form-control" value="{{ user_obj.age }}">
                <input type="submit" value="提交" class="btn btn-block btn-warning">
            </form>
        </div>
    </div>
    </div>
    {% endblock %}
    
    
    # insert.html 文件
    
    {% extends 'home.html' %}
    {% block left-body %}
        <div class="container">
        <div class="row">
            <h2 class="text-center">插入数据</h2>
            <div class="col-md-8 col-md-offset-2">
                <form action="" method="post">
                username:
                    <input type="text" class="form-control" name="name">
                password:
                    <input type="test" class="form-control" name="pwd">
                age:
                    <input type="number" class="form-control" name="age">
                    <input type="submit" value="提交" class="btn btn-block btn-warning">
                </form>
            </div>
        </div>
        </div>
    {% endblock %}
    

    image-20210319171604527

    image-20210319171632069

    image-20210319171716321

    image-20210319171748532

  • 相关阅读:
    多行文本溢出显示省略号(…)
    CSS3 grayscale滤镜图片变黑白实例页面
    腾讯TGideas语义化标签(转)
    jQuery Ajax通用js封装
    动态加载 js
    Javascript的四种继承方式
    Android四大组件之Activity
    Android四大组件通信的Intent介绍和详解
    oracle学习笔记(十四) 数据库对象 索引 视图 序列 同义词
    oracle学习笔记(十三) 查询练习(三) 子查询查询
  • 原文地址:https://www.cnblogs.com/songhaixing/p/14583253.html
Copyright © 2011-2022 走看看