【实战案例】Django框架使用模板渲染视图页面及异常处理
本文基于之前内容列表如下:
【图文指引】5分钟搭建Django轻量级框架服务
【实战案例】Django框架基础之上编写第一个Django应用之基本请求和响应
【实战案例】Django框架连接并操作数据库MySQL相关API
视图概述
Django中的视图的概念是一类具有相同功能和模板的网页的集合,在Django中,网页和其他内容都是从视图派生而来,每一个视图表现为一个Python函数(或者说方法,如果是在基于类的视图里的话),Django将会根据用户请求的URL来选择使用哪个视图(更准确的说,是根据URL中域名之后的部分),为了将URL和视图关联起来,Django使用了’URLconfs’来配置,URLconf将URL模式映射到视图。
基于之前的投票应用,在polls/views.py 里添加更多视图,与之前不同的是他们接收参数:
def detail(request, question_id):return HttpResponse("You're looking at question %s." % question_id)def results(request, question_id):response = "You're looking at the results of question %s."return HttpResponse(response % question_id)def vote(request, question_id):return HttpResponse("You're voting on question %s." % question_id)
同时将新试图添加进polls.urls模块里,只要添加几个url()函数调用就行:
from django.urls import pathfrom . import viewsurlpatterns = [# ex: /polls/path("", views.index, name="index"),# ex: /polls/5/path("<int:question_id>/", views.detail, name="detail"),# ex: /polls/5/results/path("<int:question_id>/results/", views.results, name="results"),# ex: /polls/5/vote/path("<int:question_id>/vote/", views.vote, name="vote"),
]
这时候运行项目后在地址栏中访问http://localhost:8000/polls/27/即可发现如下页面
也可以尝试 “/polls/27/results/” 和 “/polls/27/vote/”,这些将显示占位的结果和投票页面。
当请求网站的页面如"/polls/27/",Django会加载myself.urls模块,因为它被ROOT_URLCONF设置指向。它会找到名为urlpatterns的变量并按顺序遍历这些模式,在找到匹配项’polls/'之后会剥离匹配的文本(“polls/”),然后将剩余的文本"27/"发送给’polls.urls’URL 配置以进行进一步处理匹配 ‘int:question_id/’,从而调用 detail() 视图
detail(request=<HttpRequest object>, question_id=27)
问题question_id=27来自int:question_id。使用尖括号"获得"网址部分后发送给视图函数作为一个关键字参数。字符串的question_id部分定义了要使用的名字,用来识别相匹配的模式,而int部分是一种转换形式,用来确定应该匹配网址路径的什么模式。冒号: 用来分隔转换形式和模式名。
上述过程仅仅是写一个demo用于测试页面返回,实际中一个视图要做的事是返回一个包含被请求页面内容的HttpResponse对象或者抛出一个异常,如Http404,至于其他事情也可以做但理论上不属于页面的职责。
视图模板系统
为了不将页面的设计写死在视图函数的代码中,接下来使用Django的模板系统,只要创建一个视图就可以将页面的设计从代码中分离出来。
在polls应用路径下创建polls/templates/polls/index.html
创建模板文件的通用规则如下:
目录结构:在每个应用(如polls)中,应该有一个templates目录,接着在这个目录下创建一个与应用名称相同的子目录(如polls),这样可以避免模板名称冲突。
文件命名:文件命名:模板文件通常以.html为后缀,文件名应描述其功能,如index.html、detail.html等。
TEMPLATES配置:在项目的settings.py文件中,TEMPLATES设置应确保APP_DIRS为True,以允许Django在每个已安装应用的templates目录中查找模板。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>这是Polls的index模板渲染</title>
</head>
<body>{% if latest_question_list %}<ul>{% for question in latest_question_list %}<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>{% endfor %}</ul>{% else %}<p>No polls are available.</p>{% endif %}
</body>
</html>
更新polls/views.py里的index视图来使用模板:
from django.http import HttpResponse
from django.template import loaderfrom .models import Questiondef index(request):latest_question_list = Question.objects.order_by("-pub_date")[:5]template = loader.get_template("polls/index.html")context = {"latest_question_list": latest_question_list,}return HttpResponse(template.render(context, request))
上述过程载入polls/index.html模板文件,并且向它传递一个上下文(context)。这个上下文是一个字典,它将模板内的变量映射为Python对象。访问 "/polls/"会看见一个无序列表,与数据库中的数据对应,列出了之前添加的投票问题,链接指向这个投票的详情页。
render()函数
“载入模板,填充上下文,再返回由它生成的HttpResponse对象”是一个非常常用的操作流程,于是Django提供了一个快捷函数render()用它来重写index()视图:
from django.shortcuts import renderfrom .models import Questiondef index(request):latest_question_list = Question.objects.order_by("-pub_date")[:5]context = {"latest_question_list": latest_question_list}return render(request, "polls/index.html", context)
上述过程无需再导入loader和HttpResponse,当然其他函数还在使用的话就需要保持导入。
render()函数的作用和参数如下:
作用:返回一个HttpResponse对象,这个对象包含了渲染后的模板内容,用户可以在浏览器中看到这个结果。
参数:
- 第一个参数(request):传入的HTTP请求对象,包含用户请求的信息。
- 第二个参数(template_name):要渲染的模板的名称,以字符串形式表示,通常包括应用名称和模板路径。
- 第三个参数(context, 可选):一个字典,包含要传递给模板的上下文数据,以便在模板中动态显示内容。
对于第三个参数示例如下:
from django.shortcuts import renderdef my_view(request):context = {'greeting': 'Hello, World!','items': ['Item 1', 'Item 2', 'Item 3'],}return render(request, 'polls/polls/index.html', context)
在模板index.html中,可以通过以下方式访问这些数据:
<h1>{{ greeting }}</h1>
<ul>{% for item in items %}<li>{{ item }}</li>{% endfor %}
</ul>
接下来处理异常问题,拿detail举例,先在polls/views.py中更新如下代码:
from django.http import Http404
from django.shortcuts import renderfrom .models import Question# ...
def detail(request, question_id):try:question = Question.objects.get(pk=question_id)# 如果指定问题 ID 所对应的问题不存在,这个视图就会抛出一个 Http404 异常。except Question.DoesNotExist:raise Http404("Question does not exist")return render(request, "polls/detail.html", {"question": question})
polls/templates/polls/detail.html中添加代码如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>这是detail的模板渲染</title>
</head>
<body>{{ question.question_text }}
</body>
</html>
当访问数据库中不存在的id时会出现404页面,如下所示:
get_object_or_404()函数
尝试用get()函数获取一个对象,如果不存在就抛出Http404错误也是一个普遍的流程,Django也提供了一个快捷函数get_object_or_404()作用于此,下面是修改后的详情 detail()视图代码:
from django.shortcuts import get_object_or_404, renderfrom .models import Question# ...
def detail(request, question_id):question = get_object_or_404(Question, pk=question_id)return render(request, "polls/detail.html", {"question": question})
为什么使用辅助函数get_object_or_404() 而不是自己捕获ObjectDoesNotExist异常呢?还有为什么模型API不直接抛出ObjectDoesNotExist而是抛出Http404呢?
因为这样做会增加模型层和视图层的耦合性,指导Django设计的最重要的思想之一就是要保证松散耦合,一些受控的耦合将会被包含在django.shortcuts模块中。
也有get_list_or_404()函数,工作原理和get_object_or_404()一样,除了get()函数被换成了filter()函数,如果列表为空的话会抛出Http404异常。
更新polls/detail.html 模板里的代码:
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
模板系统统一使用点符号来访问变量的属性。在示例 {{ question.question_text }} 中,首先 Django 尝试对 question 对象使用字典查找(也就是使用 obj.get(str) 操作),如果失败了就尝试属性查找(也就是 obj.str 操作),结果是成功了。如果这一操作也失败的话,将会尝试列表查找(也就是 obj[int] 操作)。
在 {% for %} 循环中发生的函数调用:question.choice_set.all 被解释为 Python 代码 question.choice_set.all() ,将会返回一个可迭代的 Choice 对象,这一对象可以在 {% for %} 标签内部使用。
去除硬编码
之前polls/index.html 里编写投票链接时,链接是硬编码的:
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
这种硬编码、强耦合的方法的问题在于,在具有大量模板的项目中更改URL变得具有挑战性。
然而由于在polls.urls模块中的path()函数中定义了name参数,所以可以通过使用 {% url %} 模板标签来消除对 url 配置中定义的特定 URL 路径的依赖:
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
这个标签的工作方式是在polls.urls模块的URL定义中寻具有指定名字的条目。之前 ‘detail’ 的 URL 是在如下语句中定义的:
path("<int:question_id>/", views.detail, name="detail"),
如果想改变投票详情视图的URL,比如想改成polls/specifics/12/,就不用在模板里修改任何东西(包括其它模板),只要在polls/urls.py里稍微修改一下就行:
path("specifics/<int:question_id>/", views.detail, name="detail"),
添加不同应用的命名空间
在实际Django项目中可能会有很多个应用,Django如何分辨重名的 URL 呢?举个例子,polls应用有detail 视图,可能另一个应用也有同名的视图。Django如何知道 {% url %} 标签到底对应哪一个应用的URL呢?答案是在根 URLconf 中添加命名空间。
在polls/urls.py文件中稍作修改,加上 app_name 设置命名空间:
from django.urls import pathfrom . import viewsapp_name = "polls"
urlpatterns = [path("", views.index, name="index"),path("<int:question_id>/", views.detail, name="detail"),path("<int:question_id>/results/", views.results, name="results"),path("<int:question_id>/vote/", views.vote, name="vote"),
]
编辑 polls/index.html 文件,从:
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
修改为指向具有命名空间的详细视图:
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
相关文章:

【实战案例】Django框架使用模板渲染视图页面及异常处理
本文基于之前内容列表如下: 【图文指引】5分钟搭建Django轻量级框架服务 【实战案例】Django框架基础之上编写第一个Django应用之基本请求和响应 【实战案例】Django框架连接并操作数据库MySQL相关API 视图概述 Django中的视图的概念是一类具有相同功能和模板的网…...

设置K8s管理节点异常容忍时间
说明 每个节点上的 kubelet 需要定时向 apiserver 上报当前节点状态,如果两者间网络异常导致心跳终端,kube-controller-manager 中的 NodeController 会将该节点标记为 Unknown 或 Unhealthy,持续一段时间异常状态后 kube-controller-manage…...

什么样的JSON编辑器才好用
简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也便于机器解析和生成。随着互联网和应用程序的快速发展,JSON已经成为数据传输和存储的主要格式之一。在处理和编辑JSON数据…...

ArkUI自定义TabBar组件
在ArkUI中的Tabs,通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。其中内容是图TabContent作为Tabs的自组件,通过给TabContent设置tabBar属性来自定义导航栏样式。现在我们就根据UI设计的效果图来实现下图效果: 根…...

pair类型应用举例
在main.cpp里输入程序如下: #include <iostream> //使能cin(),cout(); #include <utility> //使能pair数据类型; #include <string> //使能string字符串; #include <stdlib.h> //使能exit(); //pair类型可以将两个相同的或不同类…...

数字 图像处理算法的形式
一 基本功能形式 按图像处理的输出形式,图像处理的基本功能可分为三种形式。 1)单幅图像 单幅图像 2)多幅图像 单幅图像 3)单(或多)幅图像 数字或符号等 二 几种具体算法形式 1.局部处理邻域对于任一…...

安徽对口高考Python试题选:输入一个正整数,然后输出该整数的3的幂数相加形式。
第一步:求出3的最高次幂是多少 guoint(input("请输入一个正整数:")) iguo a0 while i>0: if 3**i<guo: ai break ii-1print(a)#此语句为了看懂题目,题目中不需要打印出最高幂数 第二步…...
Node.js是什么? 能做什么?
Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它使用事件驱动、非阻塞式I/O模型,使得JavaScript能够在服务器端运行。Node.js允许JavaScript脱离浏览器,直接在服务器和计算机上使用,极大地扩展了JavaScript的应用范围。…...

JVM快速入门
1、 JVM探究 面试问题 :谈谈对JVM的理解? java8虚拟机和之前的变化更新?什么是OOM,什么是栈溢出StackOverFlowError?怎么分析?JVM的常用调优参数有哪些?内存快照如何抓取,怎么分析Dump文件?知道吗?谈谈JVM中,类加载器你的认识?2、JVM的位置 3、JVM的体系结构 3.1…...
理解深度学习模型——高级音频特征表示的分层理解
理解深度学习模型可以是一个复杂的过程,因为这些模型通常包含大量的参数和层次。 (1)复杂性来源: 深度学习模型的复杂性来源于多个方面,包括模型的规模、层次结构、参数数量以及训练数据的复杂性。以下是一些关键点&a…...

【HarmonyOS Next】原生沉浸式界面
背景 在实际项目中,为了软件使用整体色调看起来统一,一般顶部和底部的颜色需要铺满整个手机屏幕。因此,这篇帖子是介绍设置的方法,也是应用沉浸式效果。如下图:底部的绿色延伸到上面的状态栏和下面的导航栏 UI 在鸿蒙…...

数据结构 ——— 树的概念及结构
目录 树的结构以及示意图 树的概念编辑 树的结构与递归的关系编辑 树的结构以及示意图 树是一种非线性的数据结构,它是由 n(n>0) 个有限节点组成一个具有层次关系的集合 把这种结构叫做树是因为它看起来像一棵倒挂的树 特点: 有一个特殊的…...

初探Vue前端框架
文章目录 简介什么是Vue概述优势MVVM框架 Vue的特性数据驱动视图双向数据绑定指令插件 Vue的版本版本概述新版本Vue 3Vue 3新特性UI组件库UI组件库概述常用UI组件库 安装Vue安装Vue查看Vue版本 实例利用Vue命令创建Vue项目切换工作目录安装vue-cli脚手架创建Vue项目启动Vue项目…...

Lucas带你手撕机器学习——岭回归
岭回归(Ridge Regression) 一、背景与引入 在进行线性回归分析时,我们常常面临多重共线性的问题。多重共线性指的是自变量之间高度相关,这会导致回归系数的不稳定性,使得模型的预测能力降低。传统的线性回归通过最小…...

C2W4.LAB.Word_Embedding.Part1
理论课:C2W4.Word Embeddings with Neural Networks 文章目录 Word Embeddings First Steps: Data PreparationCleaning and tokenizationSliding window of wordsTransforming words into vectors for the training setMapping words to indices and indices to w…...

hive初体验
1.首先,确保启动了Metastore服务。 runjar就是metastore进程 2.进入hive客户端: 命令:hive 3.操作:没有指定数据库时默认在default 一:创建表:CREATE TABLE test(id INT, name STRING, gender STRING); 完成,show tables看一下 也可以通过hdfs文件系统查看,默认路径…...

云渲染主要是分布式(分机)渲染,如何使用blender云渲染呢?
云渲染主要是分布式(分机)渲染,比如一个镜头同时开20-100张3090显卡的机器渲染,就能同时渲染20-100帧,渲染不仅不占用自己电脑,效率也将增加几十上百倍! blender使用教程如下: 第一…...
WordPress与WP Engine:关键事件时间线
WordPress与WP Engine:关键事件时间线 以下时间线突出了9月和10月之间这场不断升级的WordPress与WP Engine冲突中的关键事件: 9月21日:Matt Mullenweg发布了一篇名为“WP Engine不是WordPress”的博客。 9月22日:Mullenweg批评…...

大数据治理平台建设规划方案(71页WORD)
随着信息化时代的到来,大数据已成为企业管理和决策的重要基础。然而,大数据的快速增长和复杂性给数据的管理和治理带来了巨大挑战。为了有效应对这些挑战,构建一个高效、稳定的大数据治理平台显得尤为重要。 文档介绍: 该平台旨在…...

Maven 项目管理工具
目录 Maven简介 Maven快速上手 Maven详细介绍 Maven工作机制 Maven安装及配置 使用IDEA创建Maven Web工程 Maven简介 Maven是 Apache 开源组织奉献的一个开源项目,可以翻译为“专家”或“内行”。 Maven 的本质是一个项目管理工具,将项目开发和管…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...