Django模板加载与响应

news2024/11/22 14:48:58

前言

Django 的模板系统将 Python 代码与 HTML 代码解耦,动态地生成 HTML 页面。Django 项目可以配置一个或多个模板引擎,但是通常使用 Django 的模板系统时,应该首先考虑其内置的后端 DTL(Django Template Language,Django 模板语言。

一.什么是模板

在 Django 中,模板是可以根据字典数据动态变化的,并且能够根据视图中传递的字典数据动态生成相应的 HTML 网页。Django 中使用 Template 来表示模板,Template 对象定义在 django/template/base.py 文件中,它的构造函数如下所示:

def __init__(self,template_string,origin=None,name=None,engine=None)

它只有一个必填的参数:字符串表示的模板代码。

1.模板的配置

首先按照BookStore/templates路径创建模板文件夹 templates,在 settings.py 配置文件中有一个 TEMPLATES 变量,如下所示:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],  #指定模板文件的存放路径
        'APP_DIRS': True, #搜索APP里面的所有templates目录
        'OPTIONS': {
            'context_processors': [  #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默认设置,指定了要是用的模板引擎的 Python 路径;

  • DIRS : 一个目录列表,指定模板文件的存放路径,可以是一个或者多个。模板引擎将按照列表中定义的顺序查找模板文件;

  • APP_DIRS : 一个布尔值,默认为 Ture。表示会在安装应用中的 templates 目录中搜索所有模板文件;

  • OPTIONS : 指定额外的选项,不同的模板引擎有着不同的可选参数,例如 context_processors 用于配置模板上下文处理器,在使 RequestContext 时将看到它们的作用。

  • 修改settings配置文件

    修改 settings.py 文件,设置 TEMPLATES 的 DIRS 值来指定模板的搜索目录为“templates”如下所示:

2.模板变量

前面的内容中我们提到了模板变量,并且已经使用了它,如{{name}}。

Django模板引擎通过 context_processors 这个上下文处理器来完成字典提供的值(value)

与模板变量之间的替换,也就是用字典的 vaule“乔治老师真厉害”来替换模板文件 test.html 中的变量 {{name}},这就好比字典中 key 到 vaule 的映射。而我们无需关心内部细节是如何让实现的,这些由 Django 框架自己完成。

  • 变量的命名规范

    Django 对于模板变量的命名规范没有太多的要求,可以使用任何字母、数字和下划线的组合来命名,且必须以字母或下划线开头,但是变量名称中不能有空格或者标点符号。

  • 模板变量的语法

    如何理解模板的变量语法呢?其实它有四种不同的使用场景,分别如下所示:

    • 索引 index 查询,如 {{变量名.index}},其中 index 为int类型即索引下标

    • 字典查询方法,{{变量名.key}} 其中 key 代表字典的键,如 a['b']

    • 属性或方法查询,如 {{对象.方法}} ,把圆点前的内容理解成一个对象,把圆点后的内容理解为对象里面的属性或者方法

    • 函数调用,如 {{函数名}}。

    下面我们对上面的语法依次进行说明,首先在views.py中添加如下代码:

def test_html(request):
    a = {}  # 创建空字典,模板必须以字典的形式进行传参
  	a['name'] = 'YU'
    a['course'] = ["Python", "C", "C++", "Java"]
    a['b'] = {'name': 'TX', 'address': 'https://www.baidu.com/'}
    a['test_hello'] = test_hello
    a['class_obj'] = Website()
    return render(request, 'test_html.html', a)


def test_hello():
    return '欢迎来到Django'


class Website:
    def Web_name(self):
        return 'Hello world!'

其次在templates 目录下创建名为 test_html 的 html 文件,然后添加以下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>网站的名字是{{ name }}</p>
    <p>课程包含{{ course.0 }}</p>
    <p>变量a是{{ b }}</p>
    <p>a['address']是{{b.address}}</p>
    <p>函数fuction:{{ test_hello }}</p>
    <p>类实例化对象:{{class_obj.Web_name}}</p>
</body>
</html>

 然后在 urls.py 文件中添加路由配置,如下所示:

from django.contrib import admin
from django.urls import path
from Bookstore import views


urlpatterns = [
    path('admin/', admin.site.urls),
    path('test/', views.test_html),
    path('test_html/', views.test_html)
]
  • 模板传参语法格式

    在视图函数中必须将变量封装到字典中才允许传递到模板上,语法格式如下:

    #方式1
    def xxx_view(request)
        dic = {
            "变量1":"值1",
            "变量2":"值2",
        }
        return render(request, 'xxx.html', dic)
    #方式2
    def xxx_view(request)
            变量1=值1
            变量2=值2
        return render(request, 'xxx.html', locals())

    注意:

    locals() 返回当前函数作用域内全部局部变量形成的字典。

    即将变量与值对应形成字典,并把这个字典作为 locals() 的返回值来使用。

 3.模板标签

Django 内置了许多标签用于简化模板的开发过程,同时 Django 也支持自定义标签,这极大的方便了 Web 开发者,下面我们依次进行介绍。

Django 的模板系统对标签的解释是在渲染的过程中提供相应的逻辑,比如Python 语言中 if...else 语句、with 语句、以及 for 循环等,这些在 Django 的模板系统中都有对应的标签,不过稍微复杂些。

它们的使用方式如下所示:

{% tag %}

3.1 判断逻辑的if标签

我们知道if 在 Python 语言中是判断条件是否成立的,在模板标签中它们作用是类似的,如果条件成立则显示块中的内容。模板标签规定了 if 需要与 endif 成对出现 ,使用的方式如下所示:

{% if 条件表达式1 %}
 ......
{% elif 条件表达式2 %}
......
{% elif 条件表达式3 %}
......
{% else %}
......
{% endif %}

上面的 if 示例中就是使用了开始标签和结束标签,它们分别写在了开始位置和结束位置。

注意:模板标签内部的两边空格不要省略。

那 if 标签具体又是如何使用的呢,下面我们通过一个简单的例子来看一下:

#在views.py 中添加如下代码
def test_if(request):
    dic={'x':2**4}
    return render(request,'test_if.html',dic)

在 templates 目录中创建 test_if.html 文件 ,并在body中添加以下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% if x > 0 %}
        <h2>{{ x }}是大于0的</h2>
    {% elif x == 0 %}
        <h3>{{ x }}是等于0的</h3>
    {% elif x < 0 %}
        <h4>{{ x }}是小于0的</h4>
    {% endif %}
</body>
</html>

最后在 urls.py 文件中配置路由如下所示:

path('test_if/',views.test_if)

最终结果可想而知,通过访问 127.0.0.1:8000/test_if 会得到如下显示:

从上面例子还可以看出,在 if 标签中可以使用算术操作符,如 >、<、==、<= 等符号,同时也可以使用逻辑运算符 and、or 来连接多个条件,以及使用 not 对当前条件取反。

注意:elif 和 else 这两个标签是可选的,elif 标签可以不止一个,但是 else 标签只有一个,同时也可以都不出现在 if 标签中,只使用 if 与 endif。

如果当判断的条件太多时,为了避免过多的连接操作符的出现,同样可以考虑使用嵌套的 if 标签。

格式如下所示:

{% if 条件表达式1 %}
      {% if 条件表达式 %}
       ......
      {% elif 条件表达式2 %}
       ......
      {% else %}
       ......
      {% endif %}
{% endif %}

在这里我们介绍另外一种方式来简单的演示如何使用嵌套 if 标签,在 views.py 文件中添加如下代码:

from django.template import Template, Context #调用template、以及上下文处理器方法
def Hello_MyWeb(request):
      #调用template()方法生成模板
      t = Template("""
                        {% if web.name == 'YU' %}
                              {% if printable %}
                                    <h1>Hello YU</h1>
                              {% else %}
                                    <h2>欢迎您下次访问,YU</h2>
                              {% endif %}
                        {% endif %}
                                      """)
      c = Context({'web': {'name': 'YU'}, 'printable': True})  #Context必须是字典类型的对象,用来给模板传递数据
      html = t.render(c)
      return HttpResponse(html)

3.2 Django for标签的使用

for 标签用于对可迭代对象进行遍历,包括列表、元组等,它与 Python 中的 for 语法是类似的。for 标签 使用时也需要和 endfor 标签配合使用,当然它也有不同之处,那就是它多了一个可选的 empty 标签,比如用它来显示当列表不存在或者列表中元素为空的时候要显示的内容。

它的使用格式如下:

{% for 变量 in 可迭代对象 %}
    ... 循环语句
{% empty %}
    ... 可迭代对象无数据时填充的语句
{% endfor %}

我们通过一个具体的实例来看一下它的用法,在 views.py 中添加如下代码:

def test_for(request):
      #调用template()方法生成模板
      t1 = Template("""
                    {% for item in list %}
                        <li>{{ item }}</li>
                    {% empty %}
                        <h1>如果找不到你想要,可以来百度(网址:https://www.baidu.com)</h1>
                    {% endfor %}
                              """)
      #调用 Context()方法
      c1 = Context({'list': ['Python', 'Java', 'C', 'Javascript', 'C++']})
      html = t1.render(c1)
      return HttpResponse(html)

并配置路由映射关系,如下所示:

path('test_for/',views.test_for)

访问 127.0.0.1:8000/test_for 得到如下页面:

当我们将列表改为空的时候,或者不是一个可迭代对象的时候,会得到如下页面:

提示:与 Python 中的 for 循环不同的是,for 标签只能一次性地遍历完列表中的元素,不能中断(break),也不能跳过(continue)。

3.3 for标签嵌套使用

for 标签同样可以嵌套使用,示例代码如下所示:

def test01_for(request):
    #使用嵌套for标签依次遍历列表取值
     website = Template("""
     {% for course in list01 %}
     <div>
        {% for coursename in course %}
        <p><b>{{ coursename }}</b></p>
        {% endfor %}
     </div>
     {% endfor %}
     """)
     webname = Context({'list01': [['Django', 'Flask', 'Tornado'], ['c语言', 'Django官网', 'Pytho官网']]})
     html = website.render(webname)
     return HttpResponse(html)

并配置路由映射关系,如下所示:

path('test01_for/', views.test01_for)

最后访问 127.0.0.1/test01_for 获得相应页面如下所示:

3.4forloop变量详解

在 for 标签还提供了内置变量forloop,我们可以访问这个变量的属性从而获取 for 循环迭代过程中的一些信息,比如 forloop.first,它的返回值是一个布尔值,当 for 循环迭代第一个元素的时候返回 True, 若有其余元素则返回的是 False。

forloop 的属性主要有以下几个:

变量描述
forloop.counter用来计数,查看当前迭代第几个元素(从1开始索引)
forloop.revcounter表示当前循环中剩余的未被迭代的元素数量(从1开始索引)
forloop.first如果当前迭代的是第一个元素,则为True
forloop.last如果当前迭代的是最后一个元素,则为True
forloop.parentloop在嵌套循环中,用来引用外层循环的 forloop

实例说明如下所示:

def test_forloop(request):
    a = Template("""
     {% for item in lists %}
     <div>
        <p><b>{{ forloop.counter }}:{{ item }}</b></p>
     </div>
     {% endfor %}
     """)
    b = Context({'lists': ['c语言', 'Django官网', 'Pytho官网']})
    html = a.render(b)
    return HttpResponse(html)  # 数字与元素以 1:'c语言' 的形式出现

路由映射关系,如下所示:

path('test_forloop/', views.test_forloop),

最终效果如图所示:

 二.模板的加载与响应方式

那么我们如何加载模板并响应给浏览器呢?

  • 方法一:通过 loader 获取模板,通过 HttpResponse 进行响应

    from django.http import HttpResponse
    from django.template import loader
    # 1.通过loader加载模板
    t = loader.get_template("模板文件名")
    # 2.将t转换成HTML字符串
    html = t.render(字典数据)
    # 3.用响应对象将转换的字符串内容返回给浏览器
    return HttpResponse(html)
  • 方法二:使用 render 方法直接加载并响应模板

    from django.shortcuts import render
    return render(request,'模板文件名', 字典数据)

下面我们对上述两种方式分别来说明:

#方式一
from django.http import HttpResponse
from django.template import loader # 导入loader方法
from django.shortcuts import render #导入render 方法
def test_html(request): 
    t=loader.get_template('test.html') 
    html=t.render({'name':'乔治老师真厉害'}) #以字典形式传递数据并生成html
    return HttpResponse(html) # 以 HttpResponse方式响应html
#方式二
from django.shortcuts import render #导入reder方法 
def test_html(request): 
    return render(request,'test.html',{'name':'乔治老师真厉害'}) #根据字典数据生成动态模板 

示例:

templates 目录下创建 test.html 文件并在其中添加如下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p style="font-size:50px;color:green">
        {{name}}
    </p>
</body>
</html>

提示:{{name}} 属于django模板语言的语法,代表一个变量

在 BookStore/urls.py 文件的 urlpatterns 列表中为视图函数 test_html() 配置路由映射关系。

如下所示:

from django.contrib import admin
from django.urls import path
from Bookstore import views # 这句代码自己加
​
​
urlpatterns = [
    path('admin/', admin.site.urls),
    path('test/', views.test_html)
]

最后在urls.py文件同级目录创建一个views.py文件,添加如下代码:

# 方式一
from django.template import loader  # 导入loader方法
from django.shortcuts import render  # 导入render 方法
from django.http import HttpResponse
​
def test_html(request):
    t = loader.get_template('test.html')
    html = t.render({'name': '乔治老师真厉害'})  # 以字典形式传递数据并生成html
    return HttpResponse(html)  # 以 HttpResponse方式响应html

从上述过程我们不难体会 Django 视图函数的实现流程。

首先在 templates 文件夹中新建了 test.html 文件,使用它作为模板文件;

然后我们配置了视图函数的路由映射关系;

最后定义了视图函数 test_html()。

三.render方法详解

renbder 方法的作用是结合一个给定的模板和一个给定的字典,并返回一个渲染后的 HttpResponse 对象。通俗的讲就是把字典格式的内容,加载进 templates 目录中定义的 HTML 文件,最终通过浏览器渲染呈现。

rebder() 方法的完整参数格式如下所示:

render(request, template_name, context=None, content_type=None, status=None, using=None)

以下每个参数的含义如下所示:

  • request: 是一个固定参数,用于生成响应的请求对象

  • template_name: templates 中定义的文件, 要注意路径名。比如 "templates\appname\index.html", 参数就要写"appname\index.html"

  • context: 要传入文件中用于渲染呈现的数据, 默认是字典格式;

  • content_type: 生成的文档要使用的媒体格式类型。默认为 DEFAULT_CONTENT_TYPE 设置的值;

  • status: http 的响应代码,默认是 200;

  • using: 用于加载模板使用的模板引擎的名称。

今天的分享到这里就结束了,感谢各位大大的观看,各位大大的三连是博主更新的动力,感谢谢谢谢谢谢谢谢谢各位的支持!!!!! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1050469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java】复制数组的四种方式

1. System.arraycopy() 用来将一个数组的&#xff08;一部分&#xff09;内容复制到另一个数组里面去。 定义&#xff1a; void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);例&#xff1a; int[] arr1 { 1, 2, 3, 4, 5 }; int[] arr2 new…

青藏高原1-km分辨率生态环境质量变化数据集(2000-2020)

青藏高原平均海拔4000米以上&#xff0c;人口1300万&#xff0c;是亚洲九大河流的源头&#xff0c;为超过15亿人口提供淡水、食物和其他生态系统服务&#xff0c;被誉为地球第三极和亚洲水塔。然而&#xff0c;在该地区的人与自然的关系的研究是有限的&#xff0c;尤其是在精细…

1500*C. Kefa and Park(dfstree)

Kefa and Park - 洛谷 Problem - 580C - Codeforces Examples input 4 1 1 1 0 0 1 2 1 3 1 4 output 2 input 7 1 1 0 1 1 0 0 0 1 2 1 3 2 4 2 5 3 6 3 7 output 2 解析&#xff1a; dfs遍历&#xff0c;记录前一个结点权值是否为1&#xff0c;并且累计路径1的个数…

MySQL学习笔记23

逻辑备份&#xff1a; 1、回顾什么是逻辑备份&#xff1f; 逻辑备份就是把数据库、数据表或者数据进行导出&#xff0c;导出到一个文本文件中。 2、逻辑备份工具&#xff1a; mysqldump&#xff1a;提供全库级、数据库级别以及表级别的数据备份。 mysqldumpbinlog&#xff…

1200*A. Flipping Game(前缀和)

解析&#xff1a; 100数据量&#xff0c;两层遍历每个区间&#xff0c;然后前缀和计算1的个数&#xff0c;维护最大值即可。 #include<bits/stdc.h> using namespace std; #define int long long const int N110; int n,a[N],res,sum[N]; signed main(){scanf("%ll…

[Linux调查局] 编译过程

编译过程 引子编译阶段预处理汇编编译链接 链接详解release && debug 引子 一个程序的编译分为4个部分: 预处理 头文件的展开条件编译宏的展开去掉注释 编译 生成汇编汇编 生成计算机认识的机器指令, 即二进制文件链接 将程序和 库 链接 &#x1f5e8;️这里有一个疑…

《Reinforcement Learning: An Introduction》第8章笔记

文章目录 Chapter 8 Planning and Learning with Tabular Methods8.1 Models and Planning8.2 Dyna: Integrated Planning, Acting, and Learning8.3 When the Models Is Wrong8.4 Prioritized Sweeping8.5 Expected vs. Sample Updates8.6 Trajectory Sampling8.7 Real-time D…

南京大学【软件分析】13 Static Analysis for Security

文章目录 1. Information Flow Security2. Confidentiality and Integrity3. Explicit Flows and Covert/Hidden Channels4. Taint Analysis污点分析案例 1. Information Flow Security 引起安全问题最主要的两大原因是&#xff1a;injection errors&#xff08;2013-2019排名…

Disucz插件-免费最全Disucz插件大全

在网络世界里&#xff0c;拥有一个活跃并充满吸引力的社区论坛是许多网站管理员和品牌经营者的梦想。然而&#xff0c;要让一个论坛充满活力、吸引大量用户&#xff0c;需要大量的内容。这就是为什么许多人转向Disucz插件的原因。Disucz插件不仅可以帮助您创建一个互动性强大的…

数据响应式原理

面试题&#xff1a;请阐述vue2响应式原理 vue官方阐述&#xff1a;https://cn.vuejs.org/v2/guide/reactivity.html 响应式数据的最终目标&#xff0c;是当对象本身或对象属性发生变化时&#xff0c;将会运行一些函数&#xff0c;最常见的就是render函数。 在具体实现上&#x…

基于SpringBoot的飘香水果购物网站

目录 前言 一、技术栈 二、系统功能介绍 水果信息管理 减积分管理 会员购买订单管理 首页 水果 购买水果订单管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息互联网购物的飞速发展&#xff0c;一般企业都去创建属于自己的电商平台以及购物…

crypto:大帝的密码武器

题目 下载zip之后可得到提示文本 结合题目名和文本提示可知&#xff0c;为凯撒密码 利用脚本&#xff0c;爆破位移的位数 str1 FRPHEVGL str2 str1.lower() num 1 for i in range(26):print("{:<2d}".format(num),end )for j in str2:if(ord(j)num > or…

【QT开发(6)】0926-QT 中加入 fastDDS 通信库的程序使用说明

在智能驾驶中&#xff0c;DDS有可能被广泛使用&#xff0c;因此推出这篇说明教程。 1、基于【QT开发&#xff08;5&#xff09;】教程的项目文档进行开发 2、安装DDS 查看《【eProsima Fast DDS&#xff08;1&#xff09;】安装eProsima Fast DDS》 至少安装: foonathan_m…

idea Springboot 高校科研资源共享系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 高校科研资源共享系统是一套完善的信息系统&#xff0c;结合springboot框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c; 系统具有完整的源代码和数据…

spring源码解析——IOC-开启 bean 的加载

概述 前面我们已经分析了spring对于xml配置文件的解析&#xff0c;将分析的信息组装成 BeanDefinition&#xff0c;并将其保存注册到相应的 BeanDefinitionRegistry 中。至此&#xff0c;Spring IOC 的初始化工作完成。接下来我们将对bean的加载进行探索。 BeanFactory 当我…

WinPcap4.1.3安装失败解决方法,A newer version of winpcap...

WinPcap4.1.3安装失败解决方法&#xff0c;A newer version of winpcap… 如图所示&#xff0c;提示本地安装有更高版本的WinPcap时&#xff0c;按如下操作即可解决。 找到相应文件&#xff0c;扩展名修改成如下&#xff1a; C:\Windows\SysWOW64 的wpcap.dll改成 wpcap.dll.…

微服务治理:构建强大、健壮的分布式系统

文章目录 什么是微服务治理&#xff1f;微服务治理的挑战1. 服务注册和发现2. 负载均衡3. 故障处理4. 安全性5. 监控和日志记录 构建强大的微服务治理1. 服务网格2. 服务注册和发现3. 负载均衡4. 故障处理5. 安全性6. 监控和日志记录 微服务治理的未来 &#x1f389;欢迎来到架…

ACGAN

CGAN通过在生成器和判别器中均使用标签信息进行训练&#xff0c;不仅能产生特定标签的数据&#xff0c;还能够提高生成数据的质量&#xff1b;SGAN&#xff08;Semi-Supervised GAN)通过使判别器/分类器重建标签信息来提高生成数据的质量。既然这两种思路都可以提高生成数据的质…

Oracle - 多区间按权重取值逻辑

啰嗦: 其实很早就遇到过类似问题&#xff0c;也设想过&#xff0c;不过一致没实际业务需求&#xff0c;也就耽搁了&#xff1b;最近有业务提到了&#xff0c;和同事讨论&#xff0c;各有想法&#xff0c;所以先把逻辑整理出来&#xff0c;希望有更好更优的解决方案&#xff1b;…

传统遗产与技术相遇,古彝文的数字化与保护

古彝文是中国彝族的传统文字&#xff0c;具有悠久的历史和文化价值。然而&#xff0c;由于古彝文的形状复杂且没有标准化的字符集&#xff0c;对其进行文字识别一直是一项具有挑战性的任务。本文介绍了古彝文合合信息的文字识别技术&#xff0c;旨在提高古彝文的自动识别准确性…