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

    一、模板概念

    1、Django通过模板动态生成html

    2、模板的加载位置

    模板一般建立在templates文件夹中,全局路径的设置在settings.py中

    ​ DIRS:决定了整个项目的模板路径的位置

    ​ APP_DIRS:决定每个应用的模板路径是否可用,是否在应用的templates目录中寻找模板

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]

    3、Template的作用

    ①呈现给用户的界面

    ②实现MVT中VT的解耦,VT有着N:M的关系,一个V可以调用任意的T,一个T也可以供任意的V使用

    4、模板处理的过程

    本质上是返回httpresponse.

    ①、加载

    读取指定的html文件

    from django.template import loader
    
    tp = loader.get_template('a.html')

    ②、渲染

    以context设置的数据,处理html文件中模板的语句和变量,并生成html网页内容

    # content = temp.render()  #直接加载模板,不返回任何变量
    content = temp.render(context={'msg':'哈哈哈'})  # 给前端返回msg
    return HttpResponse(content)

    ③加载以及渲染

    Django中直接可以使用render()方法返回模板页面。

    from django.shortcuts import render
    
    def index(request):
        # 本质上也是返回HttpResponse
        return render(request, 'index.html')

    5、模板引擎

    Django框架使用Django的模板引擎,本质是一个类,实现相关功能,继承自BaseEngine

    可以解释模板变量和模板标签

    二、模板变量

    1.语法

    ①html中直接访问变量:{{变量名}}

    ②点语法

    访问复杂类型变量,例如list,dict,obj类型的变量

    ​(1)获取属性:cake.name

    (2)索引:fruits.0

    (3)字典:dict.key

    from django.shortcuts import render


    def pass_dict(request):
    data = {
    'name':'apple',
    'price':12.5,
    'color':'yellow'
    }
    return render(request,'var/var_demo.html',{'mydict':data})


    class Cake:
    def __init__(self,name,price):
    self.name = name
    self.price = price

    def order_cake(self):
    return '订购一个名字为:'+str(self.name) +'价格为:'+str(self.price)+'的蛋糕'


    def pass_object(request):
    cake = Cake('生日蛋糕',12.4)
    return render(request,'var/var_object.html',{'cake':cake})


    def pass_list(request):
    fruits = ['apple','火龙果','香蕉','菠萝']
    return render(request,'var/var_list.html',{'fruits':fruits})
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        水果名称:{{ mydict.name }} <br>
        水果价格: {{ mydict.price }} <br>
        水果颜色: {{ mydict.color }}<br>
    </body>
    </html>

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        蛋糕名字:{{ cake.name }}
        蛋糕价格:{{ cake.price  }}
        调用蛋糕的无参(除了self参数)方法:{{ cake.order_cake }}
    </body>
    </html>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>fruits</title>
    </head>
    <body>
        列表的第一项:{{ fruits.0 }}
        列表的第三项:{{ fruits.2 }}
    </body>
    </html>

    2.locals()方法 

    locals() 函数会以字典类型返回当前位置的全部局部变量。

    对于函数, 方法, lambda 函式, 类, 以及实现了 call 方法的类实例, 它都返回 True

    locals 是只读的,不可修改

    from django.shortcuts import render
    
    
    def pass_dict(request):
        data = {
            'name':'apple',
            'price':12.5,
            'color':'yellow'
        }
        return render(request,'var/var_demo.html',locals())

    三、模板标签

    1、if标签

    ①语法:

    {% if 表达式 %}
        语句    
    {% elif 表达式 %}
        语句
    {% else %}
        语句
    {% endif %}

    【 注意:可以在if后添加and、or、not,逻辑判断符号。判断是否相等,使用"=="符号。】

    from django.shortcuts import render
    
    
    def if_view(request, score):
        score = float(score)
        return render(request,'tags/if_tag.html',locals())
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>if标签</title>
    </head>
    <body>
        {% if score >= 90 %}
            <h3>优秀</h3>
        {% elif score >= 80 %}
            <h3>良好</h3>
        {% elif score >= 70 %}
            <h3>一般</h3>
        {% elif score >= 60 %}
            <h3>及格</h3>
         {% else %}
            <h3 style="color: red">不及格</h3>
        {% endif %}
    </body>
    </html>

    2.for标签

    ①、语法:

    {% for 循环变量 in 循环序列 %}​
    
        {{ 循环变量 }}
    
    {% empty %}​
    
        如果循环序列为空,执行此处
    
    {% endfor %}

    注意:使用for标签循环时,有一个forloop模板变量,用来记录当前循环进度的。forloop的常用属性:counter、first、last。​ 如果要进行反向循环,则在for标签的循环序列后加上reversed。

    【empty:只有当传过来的循环序列为空的时候在会调用】

    (1)forloop.counter 表示当前是第几次循环,从1数数

    (2)forloop.counter() 表示当前是第几次循环,从0数数

    (3)forloop.revcounter 表示当前是第几次循环,倒着数数,到1停

    (4)forloop.revcounter() 表示当前第几次循环,倒着数,到0停

    (5)forloop.first  是否是第一个, 布尔值

    (6)forloop.last 是否最后一个,布尔值

    def for_view(request):
        countrys = []
        links = ['娱乐','体育','新闻','学习']
        return render(request,'tags/for_tag.html',locals())
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>for标签</title>
    </head>
    <body>
        {% for link in links %}
            {{ link }}
           {% if not forloop.last %}
              |
           {% endif %}
        {% endfor %}
    
        {% for country in countrys %}
            {{ country }}
        {% empty %}
        <h3>没有国家如何遍历?</h3>
        {% endfor %}
    
    </body>
    </html>

    3、注释

    审查元素的时候不会被看到注释掉的内容

    ①单行注释

    {#  被注释掉的内容  #}

    ②多行注释

    {% comment %}
        内容
    {% endcomment %}

    4、ifequal

    判断是否相等

    {%  ifequal  value1 value2 %}
        语句
    {% endifequal %}

    5、ifnotequal

    判断是否不等

    {%  ifnotequal  value1 value2 %}
        语句
    {% endifequal %}

    6、include标签

    include标签常用来包含那些固定不变的模板

    语法:

    ​ {% include '包含的模板地址' %}

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
    </head>
    <body>
        <h3>欢迎访问本网站</h3>
        {% include 'tags/footer.html' %}
    </body>
    </html>
    友情链接:<a href="http://www.baidu.com">百度</a>
    <a href="http://www.souhu.com">搜狐</a>
    <a href="http://www.360.com">360</a><br>
    联系电话:158XXXXXXX

    7、模板继承标签

    ①、挖坑和填坑

    父模板(基模板)提前定义若干个block块标签,子模板可以继承、重写、添加父模板block块中的内容。

    "挖坑, 填坑"可以嵌套,坑不是必须填的,没有填的坑,在html中自动过滤

    {%block name%}
    {%endblock%}

    ②、模板继承

    子模板通过{% extends '父模板位置' %}继承父模板。

    子模板如果想要在父模板的某个块中添加内容,则先要使用{{ block.super }}获取​ 父模板中该块的内容。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}{% endblock %}</title>
    </head>
    <body>
        <h3>西安欢迎你</h3>
        {% block content %}
            <h3> 西安是一座现代化城市</h3>
            {{ msg }}
        {% endblock %}
    </body>
    </html>
    {% extends 'extends/base.html' %}
    {% block title %}
        大秦帝国
    {% endblock %}
    {% block content %}
        {{ block.super }}
        <h3>大秦将要统一六国</h3>
    
        {{ info }}
    {% endblock %}
    def go_child(request):
        return render(request,'child.html',{'info':'西安市十三朝古都','msg':'这是父模板的信息'})

    【注意:子模块中只能填坑,在子模块中自己添加的东西,并不会显示在页面上】

    四、过滤器|

    1、作用

    在变量显示前修改它的值

    2、使用方法

    模板变量后面添加管道符 | ,管道符后面是过滤器名称,可以连用,过滤器之间使用|隔开

    3、常用的模板过滤器

    ①算术运算

    (1)加减  add,通过加上负数的形式实现减法

    {{ store.years|add:5 }}
    {{ store.years|add:-2 }}

    (2)乘除  {% widthratio 变量  分母  分子  %}

    {% widthratio price  10  1  %}   price = 1000时,结果为100
    {% widthratio  100 10 5%}   100的十分之五

    (3)整除  {% if  num|divisibleby:2 %}

    {% if forloop.counter|divisibleby:2 %}

    ②、字符串操作

    (1)lower 变为小写

    {{ p.pname|lower }}

    (2)upper 变为大写

    {{ p.pname|upper }}

    (3)capfirst  第一个字符转化成大写形式

    {{ value | capfirst }}

    (4)cut   从给定value中删除所有arg的值

    {{ value | cut:arg}}

    (5)truncatewords:"单词数" 截取指定数量的单词,该过滤器需要参数

    (6)truncatechars:'字符数',截取指定数量的字符,当数量<=3 时显示... 当数量>3时,后三位显示为...前面的正常显示

    ③、default默认值

    格式: {{var|default:value}}

    {{ store.address|default:'' }}

    ④、日期时间

    根据指定格式转换日期为字符串

    格式:{{  dateVal | date:'Y-m-d H:i:s a' }}

    ⑤、HTML转义

    将接收到的数据当成普通字符串处理还是当成HTML代码来渲染的一个问题

    渲染成html

    {{ code|safe}}
    {% autoescape off%}
        code
    {% endautoescape %}

    不渲染

    {{ code|escape}}
    {% autoescape on%}
        code
    {% endautoescape %}

    注意:开发中尽量保持纯文本,如果进行html渲染, 可能会被恶意注入

    ⑥其他

    (1)filesizeformat

     {{ value | filesizeformat }}

       格式化value,使其成为易读的文件大小,例如:13KB,4.1MB等。

    (2)dictsort

    {{ value | dictsort:"name"}}

    如果value的值是一个字典,那么返回值是按照关键字排序的结果

    (3)dictsortreversed

    同dictsort, 按照关键字排序的结果的反序

    (4)first

    返回列表中的第一个Item

    {{ value | first }}

    (5)last

    返回列表中的最后一个Item

    {{ value | last }}

    (6)length

    {{ value | length }}

    返回value的长度

    (7)addslashes

    在单引号、双引号、反斜线前添加斜线

    def show_filter(request):
        s = 'hello django, hello python'
        num = 100
        say = "He said:'you are stupid!'"
        t = datetime.now()
        info = '<li>我是一条info信息</li>'
    
        return render(request, 'filter/filter_demo.html', locals())
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>演示模板过滤器</title>
    </head>
    <body>
        <h3>s|length 传递的字符串s的长度{{ s|length }}</h3>
        <h3>s|capfirst 传递的字符串s的首字母大写{{ s|capfirst }}</h3>
        <h3>s|first|upper 连续调用过滤器,获取s首字母大写{{ s|first|upper}}</h3>
        <h3>s|truncatechars:"3" 选取s前三个字符{{ s|truncatechars:"3"}}</h3>
        <h3>s|truncatewords:"1" 选取s前1个单词{{ s|truncatewords:"1"}}</h3>
        <h3>s|truncatewords:"2" 选取s前2个单词{{ s|truncatewords:"2"}}</h3>
        <h3>t|date:"Y-m-d H:i:s" 当前时间{{ t|date:"Y-m-d H:i:s"}}</h3>
        <h3>t|addslashes addslashes过滤器{{ say|addslashes}}</h3>
        <h3>num|add:'5' 给变量添加5:{{ num|add:'5' }}</h3>
        <hr>
        <h3>info 未加safe过滤器{{ info }}</h3>
        <h3>info|safe 添加safe过滤器{{ info|safe }}</h3>
        添加safe后,浏览器会解析其中的标签信息
        <hr>
    
    </body>
    </html>

    4.自定义过滤器

    ①步骤

    a.在应用目录下建立templatetags包(最好创建__init__.py文件),并在此包下建立自己的过滤器模块(例如:myfilter.py)

    b.在自定义模块中导入template包:from django import template

    c.创建过滤器装饰变量:register = template.Liabry()

    d.使用装饰器装饰函数,装饰语句为:@register.filter

    e.在模板中加载过滤器模块

    ②举例

    现在有需求,在url中传递阿拉伯数字,在页面中显示其对应的大写汉字

    # 定义过滤器
    # myapp/templatetags/myfilter.py
    
    from django import template
    
    # 用来注册模板过滤器
    register = template.Library()
    
    # name属性可以给函数添加别名,不设置name属性的话在模板中可以直接使用函数名访问
    # value为形参,为模板变量,模板页面中变量通过第一个形参和过滤器交互
    # s为模板中的参数【非必须,在模板函数可以使用 函数名或别名:变量值 来进行参数传递】
    @register.filter(name='chinese_upper')
    def number_to_upper(value, s):
        list1 = ['', '', '', '', '', '', '', '', '', '', '', '']
        return list1[value] + s
     # 路由中添加
     path('custom_filter/<int:num>/', views.show_custom_filter),
    # 视图函数中添加
    def show_custom_filter(request, num):
        try:
            return render(request, 'filter/custom_filter.html', locals())
        except:
            return HttpResponse('Index Error')
    <!--模板页面-->
    <!--myapp.templates.filter.custom_filter.html-->
    
    <!DOCTYPE html>
    {% load myfilter %}
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>自定义过滤器</title>
    </head>
    <body>
        {{ num | chinese_upper:"China No.1" }}
    </body>
    </html>

     五、csrf

    1、作用

    防止跨站请求伪造,某些恶意网站包含链接js利用登陆用户在浏览器中的认证信息,进行非法操作、攻击服务、破坏数据等

    2、token

    一种口令,通常被用于验证身份

    生成规则:保证生成的数据是唯一的,例如:用户唯一, 拼接时间戳, 拼接公司域名(工程名)

         最后使用md5(摘要)(本质: 128位的2进制,转换成32个16进制, 即四个一组,将16进制转换成字符串,不管输入有多少, 输出都是定长的)

    3、使用中间件csrf_token

    增加系统的安全性,在请求头的cookie中生成了一个csrftoken键值对

    4、在<form>表单中

    使用post提交

    {% csrf_token %}

    5、settings配置

    默认情况下django中是启动了csrf_token认证的,在settings中的中间件MIDDLEWARE中配置打开'django.middleware.csrf.CsrfViewMiddleware',

    不想使用的时候: 在settings中的MIDDLEWARE中注释或删除

  • 相关阅读:
    实验
    概率与期望
    2020CSP-S模板
    洛谷:P2538 [SCOI2008]城堡
    洛谷P1731 生日蛋糕
    洛谷 P1180 石子合并
    洛谷 P2831 愤怒的小鸟
    浅谈状压DP
    浅谈线段树
    LCA-树链剖分
  • 原文地址:https://www.cnblogs.com/huiyichanmian/p/11234720.html
Copyright © 2011-2022 走看看