zoukankan      html  css  js  c++  java
  • Django-模板层

    一、django模板使用的两种方式

    本质:打开模板文件,字符串替换,retern HttpRespnse('替换完的字符串')

    view.py

    # 方式一
    def index(request):
        return render(request,'time.html',context={'current_date':str(now),'title':'这是自定义标题'})
    
    def index(request):
        current_date = str(now)
        title = '这是自定义标题'
        return render(request,'time.html',context={'current_date':current_date,'title':title})
    
    # 方式二(也叫页面静态化,提高网站并发量,以下只是页面静态化最基本的使用方式,实际中还需要其他技术引入)
        now=datetime.datetime.now()
        from djangotest import settings
        import os
        path=os.path.join(settings.BASE_DIR,'templates','time.html')
        ss=open(path,'r',encoding='utf-8').read()
        t=Template(ss)
        c=Context({'current_date':str(now),'title':'这是自定义标题'})
        html=t.render(c)  # html是渲染后的字符串
        return HttpResponse(html)
    

    time.html

    使用{{}}包括的变量,就会把这些变量渲染出来替换掉,详细看下一部分

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{{title}}</title>
    </head>
    <body>
        现在时刻是:<h1>{{current_date}}</h1>
    </body>
    </html>
    

    二、模板语法之变量

    DTL:Django Template Language,每个编程语言都会有自己的模板语法,比如java里的jsp

    views.py

    # 模板中使用 {{python变量}}
    def index(request):
        num = 10
        ss = 'yang is handsome'
        b = False
        ll = [1, 2, 43]
        dic = {'name': 'yang', 'age': 18}
    
        def test():
            print('我是test')
            return '这是测试函数test的返回值'
    
        class Person():
            def __init__(self, name):
                self.name = name
    
            def print_name(self):
                return self.name
            # 如果不重写__str__ DTL会把对象的内存地址打印出来
            def __str__(self):
                return self.name
    
        p=Person('yang')
    
        return render(request, 'index.html',{'num':num,'ss':ss,'b':b})
        #locals() 把当前作用域下所有的变量,都传到context中,当变量很多的时候使用这个
        return render(request, 'index.html',locals())
    

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{{ss}}</title>
    </head>
    <body>
    
    <h1>模板语法之变量</h1>
    <p>数字:{{ num }}</p>
    <p>字符串:{{ ss }}</p>
    <p>布尔:{{ b }}</p>
    <p>列表:{{ ll }}</p>
    <p>字典:{{ dic }}</p>
    <!--函数会直接执行,打印其返回值-->
    <p>函数:{{ test }}</p>
    <!--在这里我们打印出来的是对象的内存地址,如果想要改变直接打印对象p的显示方式,可以重写__str__方法-->
    <p>对象:{{ p }}</p>
    
    </body>
    </html>
    

    三、模板语法之深度查询句点符

    我们可以使用.(点)把一些属性或者数据点出来。

    在DTL中不支持括号,所以如果要执行函数,直接写函数名即可,因为DTL不支持括号,所以不支持用函数传递参数,即我们只能写不带参数的函数传到前端。虽然不支持函数传递参数,但是我们可以通过过滤器或者标签传递参数到视图函数中,然后进行处理。

    1.句点符举例

    views.py

    def index(request):
        ll = [1, 2, 43, {'name': 'yang'}]
        dic = {'name': 'yang', 'age': 18}
    
        def test():
            print('我是test')
            return '这是测试函数test的返回值'
    
        class Person():
            def __init__(self, name):
                self.name = name
    
            def print_name(self):
                return self.name
    
            def __str__(self):
                return self.name
    
        p = Person('yang')
    
        link1 = '<a href="https://www.baidu.com">点我<a>'
    
        link2 = mark_safe(link1)  # from django.utils.safestring import mark_safe,需要先导入
    
        input_1='<p>用户名:<input type="text" name="name"></p>'
        input_2=mark_safe(input_1)
    
    
        script_1='''
        <script>
        	alert('你被攻击了')
        </script>
        '''
        script_2 =mark_safe(script_1)
        
        return render(request, 'index.html', locals())
    

    index.html

    <h2>模板语法之句点符的深度查询</h2>
    <p>列表的第一个元素:{{ ll.1 }}</p>
    <p>字典的name对应的值:{{ dic.name }}</p>
    <p>列表的第三个元素的name对应的值:{{ ll.3.name }}</p>
    <p>函数执行,直接写函数名即可:{{ test }}</p>
    <p>函数如果有参数?不支持</p>
    <p>对象调用方法: {{ p.print_name }}</p>
    <p>对象调用属性: {{ p.name }}</p>
    <hr>
    <a href="https://www.baidu.com">点我</a>
    <p>a标签的字符串: {{ link1 }}</p>
    <p>a标签的字符串,显示成a标签: {{ link2 }}</p>
    
    <p>用户名:<input type="text" name="name"></p>
    <p>input标签:{{ input_1 }}</p>
    <p>input标签,显示成标签:{{ input_2 }}</p>
    
    <p>js原封不动显示:{{ script_1 }}</p>
    
    {{ script_2 }}
    

    2.xss攻击

    xss攻击是利用网页的漏洞,将一些攻击性代码放入网页中,当用户执行网页的时候,攻击性代码也随之运行,从而达到攻击效果。通常情况,这些恶意程序是js,java,VBScript但不局限于此。

    django已经帮我们处理了xss攻击,django利用escape转义来处理,即

    <div>就是html的关键字,如果要在html页面上呈现<div>,其源代码就必须是&lt;div&gt;转义其实就是把HTML代码给转换成HTML实体,让他原原本本的显示出来不带代码这样的特殊含义
    
    如果对于一些代码我们想让他具有代码的功能,那么我们可以使用mark_safe函数或者safe过滤器
    

    四、过滤器

    有许多的过滤器,如default,length,filesizeformat,date,slice,truncatechars,safe等等

    较为重要的是date和safe

    {{参数1|过滤器名字:参数2}}
    过滤器最多传两个值,最少一个值  {{'HelloWord'|slice:'2:3'}}
    # 记住
    # 过滤器之date:显示时间,控制输入来的时间格式,比如只显示年或者只显示年月日等,且大小写还有不同
    ctime = datetime.datetime.now()
    {{ ctime|date:'Y年m月d日-------H时i分s秒' }}
    {{ ctime|date:"Y-m-d" }}
    {{ ctime|date:"Y-M-D" }}
    -----------------------------------
    2020年10月13日-15时16分22秒
    2020-10-13
    2020-Oct-Tue
    
    # 过滤器之safe:将想显示的代码过滤出来,不打印其实体
    link1 = '<a href="http://www.baidu.com">点击跳转百度</a>'
    {{ link1|safe }}
    
    # 了解
    # filesizeformat过滤器,将值格式化为一个 “人类可读的” 文件尺寸(例如13kb,52MB)
    num = 1341414124
    {{ num|filesizeformat }}  
    ------------------
    1.2GB
    
    # slice过滤器,切割
    ss = '12345678987654321'
    {{ ss|:slice"7:11" }}
    ------------------------------
    8987
    
    # truncatechars过滤器:只显示输入参数的字符数,且因为...占了三个字符,所以这个参数输入0-2结果都一样
    ss = '12345678987654321'
    {{ ss|truncatechars:'10' }}
    -----------------------------
    1234567...
    
    # truncatewords过滤器,过滤单词,是按照空格分的
    ss = '123 456 789 876 543 21'
    {{ ss|truncatewords:'2' }}
    -------------------------------
    123 456 ...
    

    五、标签

    常用标签包括for,for ... empty,if,with,csrf_token

    # views.py
    def index(request):
        ll=['lqz','yang','zs','ls','ww']
        dic={'name':'yang','age':19}
        count=1
        lqzisnbplus='yang'
        b=True
        user_list=[{'name':'name1','age':19},{'name':'name2','age':18},{'name':'name3','age':22},{'name':'name4','age':99},{'name':'name5','age':18},{'name':'name6','age':18}]
        return render(request, 'index.html', locals())
    

    1.for标签与for...empty标签

    用法:{% 标签名 %}
    
    标签for,在标签for的内部一直有一个forloop对象,是个字典
    counter0:从0开始,每循环一次加1
    counter:从1开始,每循环一次加1
    revcounter:从列表长度开始,每循环一次减一
    first:判断是不是循环的第一个
    last:判断是不是循环的最后一个
    parentloop:父级forloop对象(for循环嵌套)
    {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 6, 'revcounter0': 5, 'first': True, 'last': False}
    
    <h2>for的用法</h2>
    {% for l in ll %}
        {# <p>{{ l }}</p> #}
        <p><a href="http://127.0.0.1:8080/{{ l }}">{{ l }}</a></p>
    {% endfor %}
    
    <hr>
    {% for k,v in dic.items %}
        <p>key值为:{{ k }},value值为{{ v }}</p>
    {% endfor %}
    
    <table border="1">
        <tr>
            <td>id号</td>
            <td>用户名</td>
            <td>年龄</td>
        </tr>
        {% for dic in user_list %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ dic.name }}</td>
                <td>{{ dic.age }}</td>
            </tr>
        {% endfor %}
    
    </table>
    
    <hr>
    <h2>for ----empty的用法</h2>
    <ul>
        {% for l in ll %}
            <li>{{ l }}</li>
        {% empty %}
            <li>没有数据</li>
        {% endfor %}
    </ul>
    
    <h2>forloop对象</h2>
    {% for dic in user_list %}
    
        {% for key,value in dic.items %}
            {{ forloop.parentloop.counter }}
            <p>{{ key }}:{{ value }}</p>
        {% endfor %}
    
    {% endfor %}
    

    2.if标签

    <h2>if</h2>
    
    {% if b %}
        <p>b是true的</p>
    {% else %}
        <p>b是false的</p>
    {% endif %}
    

    3.with标签

    with标签主要是起别名

    {% with forloop.parentloop.counter as aaa %}
        {{ aaa }}
    {% endwith %}
    
    
    {% with lqzisnbplus as a %}
    {{ a }}
    ----{{ lqzisnbplus }}
    
    {% endwith %}
    

    4.csrf标签

    <h2>csrf</h2>
    
    {% csrf_token %}
    <input type="text" name="csrfmiddlewaretoken" value="uC35XuP1J2Va74ArYiNw4TMZ0PaZ6V4qvVGCsUQcqiKF5Sr8IrWS0rzpmOmPBrjY">
    </body>
    

    六、自定义标签和过滤器

    1.自定义过滤器

    @register.filter可以加括号,加括号可以传一个safe=True的参数,设置了之后在视图函数中就不需要再使用mark_safe函数了。但是对于装饰器来说,加了括号其实是运行了,只是对于我们的这个装饰器来说,加不加都可以

    """
    第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
    第二步:在app中创建templatetags包(包名只能是templatetags,不能改)
    第三步:在包内,新建py文件(如:my_tags.py)
    第四步:写代码(过滤器)
    """
    from django import template
    register = template.Library()
    
    
    @register.filter
    def my_upper(value):
    	return value.upper()
    
    # 第五步使用:(在模板中),先load,再使用
    
    {% load my_tags %}
    {{ 'aa'|my_upper }}
    

    2.自定义标签

    """
    第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
    第二步:在app中创建templatetags包(包名只能是templatetags,不能改)
    第三步:在包内,新建py文件(如:my_tags.py)
    第四步:写代码(过滤器)
    """
    from django import template
    register = template.Library()
    
    @register.simple_tag
    def my_csrf():
    	import uuid
    	res=uuid.uuid4()
    	return mark_safe('<input type="hidden" name="csrfmiddlewaretoken" value="%s">'%res)
    
    # 第五步使用:(模板),先load,再使用
    {% load my_tags %}
    {% my_csrf %}
    {% my_tag 1 3 4 %}  # 传参数直接在后面加,用空格分隔	
    

    七、inclusion_tag的使用

    inclusion_tag实现了代码和html的分离,对于前端页面,我们只需要调用需要的标签,就能连带把这个标签绑定的html显示出来。在下面的例子中可以看到,在index.html页面上,完全没有html代码。但是依然能够渲染出页面。

    """
    可以生成一片模板中的代码块
    第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
    第二步:在app中创建templatetags包(包名只能是templatetags,不能改)
    第三步:在包内,新建py文件(如:my_tags.py)
    第四步:写代码(inclusion_tag)
    """
    from django import template
    register = template.Library()
    
    # inclusion_tag,传一个模板文件
    @register.inclusion_tag('left.html')
    def left(num):
    	dic = {i: '第%s页' % i for i in range(num)}
    	# 固定返回的必须是字典
    	return {'data': dic}
    
    @register.inclusion_tag('beautiful.html')
    def beautiful(title, url):
    	return {'title': title, 'url': url}
        
    # 第五步使用:(在模板中),先load,再使用
    {% load my_tags %}
    {% left 5%}
    {% beautiful '名字' '地址'%}
            
            
    # 它跟tag有什么不同?
    	-tag需要在代码中写html的东西
        -inclusion_tag代码跟模板分离
    
    left.html
    {% for key,value in data.items %}
    {#    <p><a href="http://127.0.0.1:8000/{{ key }}">{{ value }}</a></p>#}
        <p>key是:{{ key }}   value是:{{ value }}</p>
    {% endfor %}
    
    
    beautiful.html
    <div class="panel panel-danger">
        <div class="panel-heading">
            <h3 class="panel-title">{{ title }}</h3>
        </div>
        <div class="panel-body">
            详情点击:<a href="{{url}}">疯狂点我</a>
        </div>
    </div>
    
    index.html
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
        <title>Title</title>
    </head>
    <body>
    
    
    {% load my_tags %}
    {% left 10 %}
    
    <hr>
    {% beautiful '同性交友' 'http://www.github.com' %}
    
    <hr>
    {% beautiful '异性交友' 'http://www.cnblogs.com' %}
    
    <hr>
    {% tab_beautiful 'xxx' 'http://www.cnblogs.com'%}
    </body>
    </html>
    

    八、模板的导入和继承

    都是为了减少代码冗余

    模板导入和继承的本质,其实就是打开了两个文件,然后在相应地方直接替换

    1.模板导入

    # 第一步:新建一个 xx.html,把好看的模板写入,只需要写入部分就行了,不需要把什么html的声明标签都写入
    <div class="panel panel-danger">
    	<div class="panel-heading">
    		<h3 class="panel-title">重金求子</h3>
    	</div>
    	<div class="panel-body">
    		详情点击:<a href="http://www.baidu.com">疯狂点我</a>
    	</div>
    </div>
    # 第二步:在你想用的地方
    {% include 'xx.html' %}   	
    

    2.模板继承

    # 第一步:写一个母版,写空盒子,这里需要写一个完整的页面,然后在部分区域留空白,在空白地方写下面代码
    {% block top %}
                
    {% endblock %}
    
    # 第二步:某个页面要使用母版,引入,扩写盒子
    {% extends 'base.html' %}
    {% block top %}
    	index页面代码
    {% endblock %}
    

    具体例子

    母版,base.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        {% load static %}
        <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
        {% block css %}
    
        {% endblock %}
        <title>
            {% block title %}
            
            {% endblock %}
        </title>
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <div class="top" style="height: 200px;background-color: #1b6d85">
                {% block top %}
                
                {% endblock %}
            </div>
            <div class="body" style="height: 600px">
                <div class="col-md-3" style="height: 600px;background-color: yellow">
                   {% include 'beautiful_egon.html' %}
                    <hr>
                    {% include 'beautiful_egon.html' %}
                </div>
                <div class="col-md-9" style="height: 600px;background-color: red">
                    {% block content %}
                    
                    {% endblock %}
                </div>
            </div>
            <div class="footer" style="height: 200px;background-color: #4cae4c">
                <img src="{% get_static_prefix %}img/1.jpg" height="60"  width="60" alt="">
            </div>
        </div>
    </div>
    
    </body>
    </html>
    

    继承的页面,order.html

    {% extends 'base.html' %}
    
    {% block title %}
    order页面
    {% endblock %}
    
    {% block content %}
    <h1>我是order页面</h1>
    {% endblock %}
    
    {% block top %}
    <h1>我是order页面的头</h1>
    {% endblock %}
    

    九、引入静态文件方式

    第一种:
    /static/sdsa/sdfasdf.jpg
    第二种:
    {% load static %}
    {% static 参数(路径)%}
    第三种:
    {% load static %}
    src='{%get_static_prefiex %}拼路径'
    
    
    第一种举例: <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    第二种举例:
        {% load static %}
        <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
    第三种举例:
        {% load static %}
    	  <link rel="stylesheet" href="{% get_static_prefix %}bootstrap/css/bootstrap.min.css">
    
    # 特殊用法,即起别名
    	{% load static %}
        {% static "images/hi.jpg" as myphoto %}
         <img src="{{ myphoto }}"></img>
        
        {% load static %}
    	{% get_static_prefix as static %}
    	<img src="{{ static }}images/hi.jpg" alt="Hi!" />
    
  • 相关阅读:
    Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
    ps中的中英文对照
    2019.6.27 oracle复习 表空间
    pthon学习笔记 2020/4/6
    运维岗位发展方向
    sql server复习重点
    linux的shell script
    linux知识扫盲
    Android Studio 三、软件学习教程-知识点
    Android Studio 二、github项目下载 2019.8.23
  • 原文地址:https://www.cnblogs.com/chiyun/p/14066522.html
Copyright © 2011-2022 走看看