[Python]Django模板的配置及其语法

发布于:2022-12-02 ⋅ 阅读:(319) ⋅ 点赞:(0)

在这里插入图片描述


前言

系列文章目录
[Python]目录
视频及资料和课件
链接:https://pan.baidu.com/s/1LCv_qyWslwB-MYw56fjbDg?pwd=1234
提取码:1234



1. 模板的配置

在项目中单独创建一个文件夹templates,用于存放模板。
在这里插入图片描述
设置模板的查找路径

在这里插入图片描述
在这里插入图片描述

'DIRS': [ os.path.join(BASE_DIR, 'template') ],

2. 定义模板

定义模板其实就是定义一个html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>hello world</h1>
    {#  name 为模板等待接收的数据,需要View查询数据库传入模板  #}
    <h1>你好 {{ name }}</h1>
</body>
</html>

3. 模板的使用

调用模板分为两步骤:

  1. 找到模板,模板文件在模板目录中的相对路径 -> 返回模板对象
  2. 渲染模板

渲染模板使用Django提供的函数render()

render(request对象, 模板文件路径, 模板数据字典)
from django.shortcuts import render
from django.http import HttpRequest
from django.http import HttpResponse
from django.http import JsonResponse
from django.shortcuts import redirect
from django.urls import reverse
import json
from django.views import View


# Create your views here.
# 使用类视图
class LoginView(View):
	# get用于处理页面资源的获取
    def get(self, request):
        # 假设姓名数据为 张三
        name = '张三'
        # 组织传递给模板的数据
        # 将数据传递给模板,需要使用字典进行传递
        context = {
            'name': name
        }
        # render第一个参数为请求对象,第二个参数为模板路径,第三个参数为数据字典
        # 对模板进行渲染,并返回渲染后的页面
        return render(request, 'index.html', context)

    def post(self, request):
        return HttpResponse('post')

路由配置:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', include(('login.urls', 'login'), namespace='login')),
    path('book/', include(('book.urls', 'book'), namespace='book'))
]

from django.urls import path
from login import views

urlpatterns = [
    path('', views.login),
    path('set_cookie/', views.set_cookie),
    path('get_cookie/', views.get_cookie),
    path('del_cookie/', views.del_cookie),
    path('set_session/', views.set_session),
    path('get_session/', views.get_session),
    path('class_login/', views.LoginView.as_view())
]

在这里插入图片描述

4. 模板语法

准备将要渲染到页面的数据:

class LoginView(View):
    def get(self, request):
        # 假设从数据库中查询出来的姓名为 张三
        name = '张三'
        # 将数据传递给模板,需要使用字典进行传递
        context = {
            'name': name,
            'age': 24,
            'birthday': datetime.now(),
            'friends': ['tom', 'jack', 'rose'],
            'money': {
                '2019': 12000,
                '2020': 15000,
                '2021': 20000
            }
        }
        # render第一个参数为请求对象,第二个参数为模板路径,第三个参数为数据字典
        return render(request, 'index.html', context)

    def post(self, request):
        return HttpResponse('post')

4.1 模板变量

变量名必须由字母、数字、下划线(不能以下划线开头)和点组成。

模板变量的变量名要与传递进来的数据的变量名一致

语法如下:

{{ 模板变量 }}

模板变量可以使python的内建类型,也可以是对象。

4.2 获取指定的数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>hello world</h1>
    {#  name 为模板等待接收的数据,需要View查询数据库传入模板  #}
    <h1>你好 {{ name }}</h1>
    <p>年龄:{{ age }}</p>
    <p>生日:{{ birthday }}</p>
    <p>朋友:{{ friends }}</p>
    {#  获取列表中的某个元素,使用点+下标的方式进行获取  #}
    <p>女朋友:{{ friends.2 }}</p>
    {#  获取字典中的某个元素,使用点+key的形式获取  #}
    <p>第一年的薪资:{{ money.2019 }}</p>
</body>
</html>

在这里插入图片描述

4.3 模板中的for循环

语法:

{%  for item in items  %}
	循环体
{%  endfor  %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>hello world</h1>
    {#  name 为模板等待接收的数据,需要View查询数据库传入模板  #}
    <h1>你好 {{ name }}</h1>
    <p>年龄:{{ age }}</p>
    <p>生日:{{ birthday }}</p>
    <p>朋友:</p>
    <ul>
        {#    for 循环    #}
        {% for friend in friends %}
            {#    forloop.counter 获取循环的次序,forloop.count0 获取下标    #}
            <li>{{ forloop.counter }} {{ forloop.counter0 }} {{ friend }}</li>
        {% endfor %}
    </ul>
    {#  获取列表中的某个元素,使用点+下标的方式进行获取  #}
    <p>女朋友:{{ friends.2 }}</p>
    {#  获取字典中的某个元素,使用点+key的形式获取  #}
    <p>第一年的薪资:{{ money.2019 }}</p>
</body>
</html>

在这里插入图片描述

4.4 if语句

语法:

注意:符号的两边要有空格

{% if age < 10 %}
    ...
{% elif age >= 10 and age < 20 %}
    ...
{% else %}
    ...
{% endif %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>hello world</h1>
    {#  name 为模板等待接收的数据,需要View查询数据库传入模板  #}
    <h1>你好 {{ name }}</h1>
    <p>年龄:{{ age }}</p>
    <p>
        {% if age < 10 %}
            年龄小于10
        {% elif age >= 10 and age < 20 %}
            年龄大于10小于20
        {% else %}
            年龄大于20
        {% endif %}
    </p>
    <p>生日:{{ birthday }}</p>
    <p>朋友:</p>
    <ul>
        {#    for 循环    #}
        {% for friend in friends %}
            {#    forloop.counter 获取循环的次序,forloop.count0 获取下标    #}
            <li>{{ forloop.counter }} {{ forloop.counter0 }} {{ friend }}</li>
        {% endfor %}
    </ul>
    {#  获取列表中的某个元素,使用点+下标的方式进行获取  #}
    <p>女朋友:{{ friends.2 }}</p>
    {#  获取字典中的某个元素,使用点+key的形式获取  #}
    <p>第一年的薪资:{{ money.2019 }}</p>
</body>
</html>

在这里插入图片描述

4.5 模板语法中的运算符

比较运算符如下:

==
!=
<
>
<=
>=

布尔运算符如下:

and
or
not

4.6 模板语法中的注释

1)单行注释语法如下:

{# 注释内容 #}

2)多行注释使用comment标签,语法如下:

{% comment %}
	注释内容
{% endcomment %}

5. 过滤器

Django v4.0 中文文档

过滤器的本质为一个函数。

语法如下:

变量|过滤器:参数
  • 使用管道符号|来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中。
  • 如果过滤器需要参数,则使用冒号:传递参数。

常见的过滤器:

  • safe,禁用转义,告诉模板这个变量是安全的,可以解释执行
  • length,长度,返回字符串包含字符的个数,或列表、元组、字典的元素个数。
  • default,默认值,如果变量不存在时则返回默认值。
  • date,日期,用于对日期类型的值进行字符串格式化,常用的格式化字符如下:
    • Y表示年,格式为4位,y表示两位的年。
    • m表示月,格式为01,02,12等。
    • d表示日, 格式为01,02等。
    • j表示日,格式为1,2等。
    • H表示时,24进制,h表示12进制的时。
    • i表示分,为0-59。
    • s表示秒,为0-59。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>hello world</h1>
    {#  name 为模板等待接收的数据,需要View查询数据库传入模板  #}
    <h1>你好 {{ name }}</h1>
    <p>年龄:{{ age }}</p>
    <p>
        {% if age < 10 %}
            年龄小于10
        {% elif age >= 10 and age < 20 %}
            年龄大于10小于20
        {% else %}
            年龄大于20
        {% endif %}
    </p>
    <p>生日:{{ birthday|date:'Y-m-d H:i:s' }}</p>
    <p>朋友:</p>
    <ul>
        {#    for 循环    #}
        {% for friend in friends %}
            {#    forloop.counter 获取循环的次序,forloop.count0 获取下标    #}
            <li>{{ forloop.counter }} {{ forloop.counter0 }} {{ friend }}</li>
        {% endfor %}
    </ul>
    {#  获取列表中的某个元素,使用点+下标的方式进行获取  #}
    <p>女朋友:{{ friends.2 }}</p>
    {#  获取字典中的某个元素,使用点+key的形式获取  #}
    <p>第一年的薪资:{{ money.2019 }}</p>
</body>
</html>

在这里插入图片描述

6. 模板继承

模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。

父模板:
如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。

标签block:
用于在父模板中预留区域,留给子模板填充差异性的内容,预留区域的名字不能相同。 为了更好的可读性,建议给endblock标签也写上名字,这个名字与对应的block名字相同。父模板中也可以使用传递过来的数据。

语法:

{% block 名称 %}
	预留区域,可以编写默认内容,也可以不编写默认内容
{% endblock 名称 %}

子模板:
标签extends:继承,写在子模板文件的第一行。

语法:

{% extends "父模板路径" %}

填充父模板中指定名称的预留区域。

子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值。

{% block 名称 %}
	重写预留区域
{% endblock 名称 %}

父模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {% block title %}
            页面标题
        {% endblock title %}
    </title>
</head>
<body>
    {% block header %}
        <h1>页面的顶部</h1>
    {% endblock header %}

    {% block main %}
        <h1>页面的主要部分</h1>
    {% endblock main %}

    {% block footer %}
        <h1>页面的底部</h1>
    {% endblock footer %}
</body>
</html>

继承父模板重写index.html:

{# 继承父模板 #}
{% extends "base.html" %}

{# 重写页面标题区域 #}
{% block title %}
    张三的个人介绍
{% endblock title %}

{# 重写页面的主体区域 #}
{% block main %}
    <h1>hello world</h1>
    {#  name 为模板等待接收的数据,需要View查询数据库传入模板  #}
    <h1>你好 {{ name }}</h1>
    <p>年龄:{{ age }}</p>
    <p>
        {% if age < 10 %}
            年龄小于10
        {% elif age >= 10 and age < 20 %}
            年龄大于10小于20
        {% else %}
            年龄大于20
        {% endif %}
    </p>
    <p>生日:{{ birthday|date:'Y-m-d H:i:s' }}</p>
    <p>朋友:</p>
    <ul>
        {#    for 循环    #}
        {% for friend in friends %}
            {#    forloop.counter 获取循环的次序,forloop.count0 获取下标    #}
            <li>{{ forloop.counter }} {{ forloop.counter0 }} {{ friend }}</li>
        {% endfor %}
    </ul>
    {#  获取列表中的某个元素,使用点+下标的方式进行获取  #}
    <p>女朋友:{{ friends.2 }}</p>
    {#  获取字典中的某个元素,使用点+key的形式获取  #}
    <p>第一年的薪资:{{ money.2019 }}</p>
{% endblock %}

{# 不需要底部区域,重写底部区域 #}
{% block footer %}{% endblock %}

在这里插入图片描述

7. jinja2模板

Jinja2:是 Python 下一个被广泛应用的模板引擎,是由Python实现的模板语言,他的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能,尤其是Flask框架内置的模板语言。

7.1 安装jinja2模板

pip install jinja2
pip3 install jinjia2 -i https://pypi.tuna.tsinghua.edu.cn/simple 

7.2 Django配置jinja2

在settings.py文件:

TEMPLATES = [
    {
        # 'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 修改为jinja2模板
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [ os.path.join(BASE_DIR, 'template') ],
        'APP_DIRS': True,
        'OPTIONS': {
            # 默认的
            # 'environment': 'jinja2.Environment',
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

报错的话,使用下面的配置设置:
ERRORS: ?: (admin.E403) A 'django.template.backends.django.DjangoTemplates' instance must be configured in TEMPLATES in order to use the admin application.
来源:08、jinja2模板使用

TEMPLATES = [
    {
        # 'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 修改为jinja2模板
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [ os.path.join(BASE_DIR, 'template') ],
        'APP_DIRS': True,
        'OPTIONS': {
            # 设置jinja2的环境变量
            # 默认设置就为这个,可以不用配置该项
            # 'environment': 'jinja2_env.environment',
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
	{
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [ os.path.join(BASE_DIR, 'template') ],
        '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',
            ],
        },
    },
]

7.3 jinja2模板与Django自带模板的区别

  1. jinja2模板没有多行注释

    {% comment %}
    	注释内容
    {% endcomment %}
    
  2. jinja2模板中的过滤器使用的就是函数,不为变量|过滤器:参数,如:在Django自带的模板中date过滤器的写法为birthday|date:'Y-m-d H:i:s',在jinja2中直接写函数形式date(birthday)

  3. jinja2中不存在forloop,使用的为loop,jinja2中的loop:
    在这里插入图片描述

{# 继承父模板 #}
{% extends "base.html" %}

{# 重写页面标题区域 #}
{% block title %}
    张三的个人介绍
{% endblock title %}

{# 重写页面的主体区域 #}
{% block main %}
    <h1>hello world</h1>
    {#  name 为模板等待接收的数据,需要View查询数据库传入模板  #}
    <h1>你好 {{ name }}</h1>
    <p>年龄:{{ age }}</p>
    <p>
        {% if age < 10 %}
            年龄小于10
        {% elif age >= 10 and age < 20 %}
            年龄大于10小于20
        {% else %}
            年龄大于20
        {% endif %}
    </p>
{#    <p>生日:{{ birthday|date:'Y-m-d H:i:s' }}</p>#}
    <p>朋友:</p>
    <ul>
        {#    for 循环    #}
        {% for friend in friends %}
            {#    forloop.counter 获取循环的次序,forloop.count0 获取下标    #}
            <li>{{ loop.index }} {{ loop.index0 }} {{ friend }}</li>
        {% endfor %}
    </ul>
    {#  获取列表中的某个元素,使用点+下标的方式进行获取  #}
    <p>女朋友:{{ friends.2 }}</p>
    {#  获取字典中的某个元素,使用点+key的形式获取  #}
    <p>第一年的薪资:{{ money.first }}</p>
{% endblock %}

{# 不需要底部区域,重写底部区域 #}
{% block footer %}{% endblock %}

在这里插入图片描述

7.4 jinja2过滤器

在jinja2_env.py文件中设置jinja2的过滤器.

jinja2_env.py 定义在项目的文件夹目录下

在这里插入图片描述

from jinja2 import Environment
# 导入Django中模板的过滤器函数
from django.template.defaultfilters import date


def environment(**options):
    # 创建Environment实例
    env = Environment(**options)
    # 指定jinja2的函数执行django的指定过滤器
    env.globals.update({
        'data': date
    })
    return env

修改配置jinja2的环境配置:

TEMPLATES = [
    # jinja2模板配置
    {
        # 'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 修改为jinja2模板
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [ os.path.join(BASE_DIR, 'template') ],
        'APP_DIRS': True,
        'OPTIONS': {
            # 设置jinja2的环境变量
            # jinja2的默认环境
            # 'environment': 'jinja2.Environment',
            # 我们自己的jinja2环境
            'environment': 'django_pro2.jinja2_env.environment',
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
    # Django自带模板配置
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [ os.path.join(BASE_DIR, 'template') ],
        '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',
            ],
        },
    },
]

使用jinja2过滤器:

{# 继承父模板 #}
{% extends "base.html" %}

{# 重写页面标题区域 #}
{% block title %}
    张三的个人介绍
{% endblock title %}

{# 重写页面的主体区域 #}
{% block main %}
    <h1>hello world</h1>
    {#  name 为模板等待接收的数据,需要View查询数据库传入模板  #}
    <h1>你好 {{ name }}</h1>
    <p>年龄:{{ age }}</p>
    <p>
        {% if age < 10 %}
            年龄小于10
        {% elif age >= 10 and age < 20 %}
            年龄大于10小于20
        {% else %}
            年龄大于20
        {% endif %}
    </p>
    {#  使用jinja2中的过滤器  #}
    {#  第一个参数为需要进行过滤处理的数据,第二个参数为过滤器需要传递的参数  #}
    <p>生日:{{ date(birthday, 'Y-m-d H:i:s') }}</p>
    <p>朋友:</p>
    <ul>
        {#    for 循环    #}
        {% for friend in friends %}
            {#    forloop.counter 获取循环的次序,forloop.count0 获取下标    #}
            <li>{{ loop.index }} {{ loop.index0 }} {{ friend }}</li>
        {% endfor %}
    </ul>
    {#  获取列表中的某个元素,使用点+下标的方式进行获取  #}
    <p>女朋友:{{ friends.2 }}</p>
    {#  获取字典中的某个元素,使用点+key的形式获取  #}
    <p>第一年的薪资:{{ money.first }}</p>
{% endblock %}

{# 不需要底部区域,重写底部区域 #}
{% block footer %}{% endblock %}

在这里插入图片描述

7.5 修改pycharm的模板引擎

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.6 自定义过滤器

在jinja2_env.py文件中自定义过滤器

from jinja2 import Environment
# 导入Django中模板的过滤器函数
from django.template.defaultfilters import date


def environment(**options):
    # 创建Environment实例
    env = Environment(**options)
    # 指定jinja2的函数执行django的指定过滤器
    env.globals.update({
        'date': date,
        # 将自定义的过滤器添加
        'do_listreverse': do_listreverse
    })
    return env


# 1.自定义过滤器
def do_listreverse(li):
    if li == "B":
        return "哈哈"



{# 继承父模板 #}
{% extends "base.html" %}

{# 重写页面标题区域 #}
{% block title %}
    张三的个人介绍
{% endblock title %}

{# 重写页面的主体区域 #}
{% block main %}
    <h1>{{ do_listreverse('B') }}</h1>
{% endblock %}

{# 不需要底部区域,重写底部区域 #}
{% block footer %}{% endblock %}

在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到