Django模板的使用以及jinja2的配置

模板用于快速生成动态页面返回给客户端,模板是一个文本,用于分离文档的表现形式和内容.模板定义了占位符以及各种用于规范文档该如何现实的模板标签.模板通常用于产生html,但是django的模板也能产生任何基于文本格式的文档.模板包含两个部分:

  • html代码
  • 模板标签

一、模板位置

  • 在应用中建立templates目录,有多个应用的时候不能复用页面

  • 第二种是放在工程的目录下,好处是如果有多个应用,可以调用相同的页面,需要注册

    • 需要修改项目的配置文件settings.py

    • TEMPLATES = [
          {
              'BACJEND':'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',
                  ]
              }
          }
      ]
      

二、模板的渲染

  1. loader加载

    好处是可以加载一次模板,然后进行多次渲染

    from django.template import loader
    def index(request):
        temp = loader.get_template('index.html')
        print(temp.__dict__)
        # 渲染模板生成HTML源码
        res = temp.render(context={'content':'hello world'})
        print(res)
        return HttpResponse(res)    
    
  2. render

    from django.shortcuts import render
    def index(request):
    	return render(request,templatename,context=None)
    

三、模板语法

Django模板中包含两个部分:变量和内置标签.变量会在模板渲染时被其值代替,内置标签负责逻辑控制.

1. 变量

变量在模板中表示:{{变量名}},变量名就是render中context中的键. 变量可以是基本类型中的数值,string,boolean,也可以是directory,object,list等. Django提供了点号来访问复杂的数据结构

  • 列表,元组的元素可以使用索引引用,不能使用负索引, 语法: 变量.index
  • 字典: 字典变量.key
  • 对象: 对象.属性 对象.方法名 (方法不能有参数)

当模板系统在变量名中遇到点的时候,按照以下顺序进行查找:

  • 字典类型查找
  • 属性方法查找
  • 方法调用
  • 列表类型索引

如果模板中引用变量未传值,则会被置为空,不会报错,除非你对其进行了其他操作

2. 过滤器

​ 过滤器是在变量显示之前修改它的值的一个方法,过滤器使用管道符,可以串联使用
​ {{ 变量 | 方法 | 方法2 … }}

  • 常见过滤器方法:
方法名作用示例
default缺省值{{ li | default:“缺省值” }}
default_if_none如果缺省值是none,则显示缺省值{{ value | default_if_none: ‘hello’ }}
cut从字符中删除指定字符{{ value | cut: ‘’ }} 删除value所有空格
length获取字符串或列表的长度
lower
upper
truncatechars截取字符串前n个字符{{ value| truncatechars: 9 }}
date格式化日期字符串{{ value| date : “Y-m-d H-i-s” }}
add添加变量的值{{ num | add: “3” }}
divisibleby把变量的值除以指定值
first列表第一个元素
last列表最后一个元素
join将列表内容连接成一个字符串{{ value| join: ‘-’ }}
autoescape设置或取消转义{ % autoescape off %} {{ data }} {% endautoescape %}
  • 自定义过滤器

    • 在app包里创建一个包: templatetags

    • 在包里创建一个py文件

      from django import template
      # 实例化自定义过滤器注册对象
      register = template.Library()
      # name代表在模板中使用的过滤器的名称
      @register.filter(name='xxx')
      def send_time(value,arg):
          """
          :param value:
          :return:
          1. 如果时间间隔小于1min内,那么显示刚刚
          2. 如果时间间隔大于1min小于1hour,那么显示xx分钟前
          3. 如果时间间隔大于1hour小时24小时,显示xx小时前
          4. 如果时间间隔大于24小时小于30天,显示xx天前
          5. 如果时间大于30天,那么显示具体时间
          """
          if not isinstance(value,datetime.datetime):
              return value
          now = datetime.datetime.now()
          timestamp = (now-value).total_seconds()
          if timestamp<60:
              return "刚刚"
          elif timestamp>=60 and timestamp< 60*60:
              return '{}分钟前'.format(timestamp /60)
          elif timestamp >= 60*60 and timestamp<60**2*24:
              return '{}小时前'.format(timestamp/(60**2))
          elif timestamp>=60**2*24 and timestamp<60**2*24*30:
              return '{}天前'.format(timestamp/(60**2*24))
          else:
              return values.strftime('%Y-%m-%d %H:%M:%S')
      
    • 在模板中使用

      {% load customfilter %} # 加载自定义过滤器的模块
      <!DOCTYPE html>
      <html lang="en">
      <head>
       <meta charset="UTF-8">
       <title>Title</title>
      </head>
      <body>
      {{ name | send_time :' how are you' }} #使⽤⾃定义过滤器
      </body>
      </html>
      
3. 内置标签

语法: {% tag %}

  1. 1 if 标签

  2. 2 for标签

变量名称变量说明
forloop.counter过去迭代的索引 从1开始
forloop.counter0
forloop.revcounter
forloop.revcounter0
forloop.first是否为第一次迭代
forloop.last是否为最后一次迭代
forloop.parentloop获取上层迭代对象
  1. 3 ifequal/ifnotequal 用于判断两个值是否相等

    {% ifequal/ifnotequal value value %}{% endifequal/endifnotequal%}

  2. 4 注释

  • 单行注释 {# 注释的内容 #}
  • 多行注释 {% comment %}…{% endcomment %}
  1. 5 跨站请求伪造 csrf

    防止网站受第三方服务器的恶意攻击(确定表单是不是本网站的表单传递过来的). csrf相当于在表单中添加了一个而隐藏input表单域,用于向服务器提交一个唯一的随机字符串用于服务器验证表单是否是本服务器的表单.

    使用:

    # settings.py
    MIDDLEWARE = [
        'django.middleware.csrf.CsrfViewMiddleware',
    ]
    
    <form action='' method='post'>
        {% csrf_token %}
        <input type='text' name='username'>
        <p><input type='submit' value='提交'></p>
    </form>
    
    • 全站禁用csrf

      只要将settings里的中间键注释就可以了

    • 局部禁用csrf

      # 在不想检验csrf的视图函数前添加装饰器@csrf_exempt
      from django.view.decorators.csrf import csrf_exempt,csrf_protect
      
      @ csrf_exempt
      def csrf1(request):
          pass
      
    • Ajax验证csrf

      Ajax提交数据的时候,携带CSRF:

      a. 放置在data中携带:

      <form method="POST" action="/csrf1.html">
       {% csrf_token %}
       <input id="username" type="text" name="username" />
       <input type="submit" value="提交"/>
       <a οnclick="submitForm();">Ajax提交</a>
      </form>
      <script src="/static/jquery-1.12.4.js"></script>
      <script>
       function submitForm(){
       var csrf = $('input[name="csrfmiddlewaretoken"]').val();
       var user = $('#user').val();
       $.ajax({
       url: '/csrf1.html',
       type: 'POST',
       data: { "user":user,'csrfmiddlewaretoken': csrf},
       success:function(arg){
       console.log(arg);
       }
       })
       }
      </script>
      

      csrf的意义在于 给每⼀个表单都设置⼀个唯⼀的csrf的值 并且cookie也存储⼀份 当提交表单过来的时候 判断cookie中的值 和csrf_token中的值 是否都为本⽹站⽣ 成的 如果验证通过则提交 否则 403

  2. 6 模板中导入标签 include

    {% include ‘路径/xxx.html’ %}

  3. 7 url标签

    在模板中url标签可用于反向解析

    <h2>
        <a href='{% url "App:index" % }'>动态生成路由地址不带参数的跳转</a>
    </h2>
    <h2>
        <a href='{% url "App:args1" 1 2 %}'>动态生成路由带参数的跳转</a>
    </h2>
    <h2>
        <a href='{% url "App:args1" num1=1 num2=2 %}'>动态生成路由地址带关键字参数的跳转</a>
    </h2>
    

四、 模板继承

  • {% extend ‘base.html’%} 继承父模板
  • {% block %} 子模版可以重载这个部分内容
  • {{ block.super }}

五、静态资源配置

什么是静态资源: css,js,images … 需要从外部导入的资源

  1. 创建static文件夹(通常放在根目录下)

  2. 需要在settings中注册

    STATIC_URL = '/static/'
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,'static'),
    ]
    
  3. 在模板中使用静态资源

    {% load static %} # 放置到模板的开头
    <img src='/static/img/img.png' alt=''> # 硬编码
    <img src='{% static "img/img.png" %}' alt=''> # 动态写法,建议使用
    

六、jinja2模板引擎配置

  • 安装jinja2模板引擎

    pip install jinja2
    
  • 配置jinja2环境变量

    # 在应用的目录下,创建一个jinja2_env.py 配置文件
    from django.contrib.staticfiles.storage import staticfiles_storage
    from django.urls import reverse
    from jinja2 import Environment
    
    def enviroment(**options):
        env = Environment(**options)
        env.globals.update({
            'static':staticfiles_storage.url,
            'url':reverse,
        })
        return env
    
  • 配置(settings.py)

    • 独立使用jinja2,不使用Django模板引擎

      # 独立使用jinja2
      INSTALLED_APPS = [
          # 'django.contrib.admin', # 注释了admin
          # .....
      ]
      
      # 模板配置
      TEMPLATES = [
          {
              # 'BACKEND': 'django.template.backends.django.DjangoTemplates',
              'BACKEND': 'django.template.backends.jinja2.Jinja2', # 设置为jinja2模板
              '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',
                  ],
                  'environment':'App.jinja2_env.environment', # 配置环境,jinjia2的配置文件位置
              },
          },
      ]
      
      
    • 两个共同使用

      # 模板配置
      TEMPLATES = [
          {
              'BACKEND': 'django.template.backends.jinja2.Jinja2', # 设置为jinja2模板
              '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',
                  ],
                  'environment':'App.jinja2_env.environment', # 配置环境,jinjia2的配置文件位置
              },
          },
          {
              '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',
                  ],
              },
          },
      ]
      
      
    • 静态资源和url

      <p>
          <a href='{{ url('app:index')}}'>dddd</a>
      </p>
      <img src='{{ static("images/1.jpg")}}' alt=''>
      
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Evan.sun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值