版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第16章Django核心组件详解《Python程序开发案例教程(第2版))》学习目标/Target
熟悉路由系统,能够归纳路由系统处理请求的过程以及URL匹配的规则掌握路由转换器的使用,能够使用内置转换器和自定义转换器限制URL模式中的参数类型掌握路由分发的方式,能够使用include()实现路由分发的功能掌握向视图传递额外参数的方式,能够通过path()函数向视图传递额外参数熟悉反向解析URL的方式,能够通过reverse()函数实现反向解析URL的功能学习目标/Target
掌握模型的定义与使用,能够根据需求定义模型和使用模型熟悉模型的字段,能够归纳常见字段的功能掌握数据的增删改查操作,能够通过objects管理器实现添加、查询、更新和删除数据的功能掌握模板,能够在项目中使用模板以及语法规则熟悉视图,能够归纳请求对象和响应对象的常见属性和方法学习目标/Target
掌握生成响应的方式,能够通过render()函数生成响应掌握视图类的定义与使用方式,能够定义与使用视图类熟悉分页的实现方式,能够通过Paginator类的属性和方法实现分页的功能章节概述/SummaryDjango是一个功能强大的Web应用框架,它内部集成了大量的组件,核心组件包括路由系统(Routingsystem)、模型(Model)、模板(Template)、视图(View)等,这些组件之间相互协作,为构建可靠、高效且易于维护的Web应用提供了极大的支持,让开发过程变得简便而灵活。本章将重点介绍路由系统、模型、模板、视图这几个核心组件。目录/Contents010203路由系统模型模板04视图05实例:用户登录路由系统16.1
先定一个小目标!熟悉路由系统,能够归纳路由系统处理请求的过程以及URL匹配的规则16.1.1路由系统简介路由系统简介在Django中,路由系统扮演着非常重要的角色,它负责接收客户端发送的请求,并将其分派给相应的视图进行处理。处理完请求后,路由系统会将视图返回的响应发回至客户端。这个过程中,路由系统起到了一个中介的角色,建立了请求和视图之间的联系。16.1.1路由系统简介路由系统简介16.1.1路由系统简介Django会按照以下流程处理HTTP请求,具体过程如下。加载项目的配置文件,从配置文件中查找配置项ROOT_URLCONF对应的值,以获取根URLconf,即根URL配置文件。从根URLconf中查找urlpatterns,将请求的URL与urlpatterns中定义的URL模式按顺序逐个进行匹配。如果成功匹配到URL模式,那么停止匹配,并调用该URL模式对应的视图返回响应。如果没有匹配到URL模式,或匹配过程中出现异常,那么Django的路由系统会调用错误处理视图并返回响应。路由系统简介16.1.1路由系统简介一个项目允许有多个urls.py,但Django需要一个urls.py作为入口,这个作为入口的urls.py就是根URLconf,它由settings.py文件中的配置项ROOT_URLCONF指定。通常情况下,配置项ROOT_URLCONF的值为“项目名.urls”。例如,在mysite项目的配置文件中ROOT_URLCONF的值为mysite.urls.py,示例代码如下:ROOT_URLCONF="mysite.urls"ROOT_URLCONF指定了mysite目录下的urls.py作为根URLconf。路由系统简介16.1.1路由系统简介为了保证项目结构清晰,开发人员通常会在Django项目的每个应用下创建urls.py文件,用于配置该应用的URL模式。当Django的路由系统接收到请求后,先根据请求的URL匹配根URLconf,找到匹配的子应用,再进一步匹配子URLconf,直到匹配完成。URL模式配置有着一定的格式要求。下面看一下mysite项目中应用hello的URL模式,具体代码如下所示:16.1.1路由系统简介路由系统简介urlpatterns=[path('',views.index)]变量urlpatterns的值是一个列表,该列表的元素是使用path()函数匹配的URL模式。path()函数定义在django.urls模块中,它的语法格式如下:16.1.1路由系统简介路由系统简介path(route,view,kwargs=None,name=None)语法格式route:必选参数,表示匹配的URL模式,它的值是一个字符串。注意,字符串中可以包含以“<>”标识的捕获参数,一般格式为<参数名>,这些参数将以关键字参数的形式传递给视图。view:必选参数,表示视图函数。当Django匹配到URL模式后会调用相应的视图函数,并将django.http.HttpRequest对象作为第一个参数传递给视图函数。kwargs:可选参数,用于接收URL地址中的任意关键字参数,并将其组织为一个字典类型的数据传递给目标视图。name:可选参数,用于为URL模式取名,以便Django可以在任意地方可以唯一引用。使用path()函数对URL模式进行匹配时,不会对URL中的协议类型、域名、端口号进行匹配。例如,path()函数在匹配:8000/hello/时,只会匹配/hello/。结合对path()函数的功能分析以上示例中的URL配置可知:当请求的URL匹配到“/”时,它会在列表urlpatterns中找到匹配的元素,并调用视图views.index,即调用views.py文件中定义的index()函数,并在该函数中传入django.http.HttpRequest对象。16.1.1路由系统简介路由系统简介
先定一个小目标!掌握路由转换器的使用,能够使用内置转换器和自定义转换器限制URL模式中的参数类型16.1.2路由转换器路由转换器格式16.1.2路由转换器URL模式中可以包含各种类型的参数,比如字符串、整数等。然而,在有些场景下需要确保参数的类型是固定的。例如根据ID值从数据库查询数据时,ID值必须是整数类型。为了满足这个需求,Django设计了路由转换器。路由转换器用于将URL模式中的参数转换为指定的类型,以确保参数类型的准确性和一致性。<路由转换器:参数名>语法格式Django内置了5种路由转换器,并支持开发人员自定义路由转换器。1.内置路由转换器Django内置了5种路由转换器,这些路由转换器的功能具体如下。str:匹配任何非空字符串,但不包含分隔符“/”。若URL模式中没有为参数指定路由转换器,则默认使用该路由转换器。int:匹配0或任何正整数。slug:匹配由字母、数字、连字符和下画线组成的字符串,例如type_blog-django。uuid:匹配UUID格式的字符串。转换器必须包含连字符,且所有字母均为小写,以避免多个URL映射到同一页面。例如59c08cbe-b828-11e9-a3b8-408d5c7ffd28。path:匹配任何非空字符串,包括分隔符“/”。16.1.2路由转换器1.内置路由转换器16.1.2路由转换器在mysite项目的urls.py中增加使用路由转换器的代码,分别使用上述5种路由转换器定义URL模式,具体代码如下:urlpatterns=[……path('str/<str:str_type>',views.index),#使用路由转换器strpath('int/<int:int_type>',views.index),#使用路由转换器intpath('slug/<slug:slug_type>',views.index),#使用路由转换器slugpath('uuid/<uuid:uuid_type>',views.index),#使用路由转换器uuidpath('path/<path:path_type>',views.index),#使用路由转换器path]示例2.自定义路由转换器自定义路由转换器本质上是一个类,这个类需要包含类属性regex、类方法to_python()和to_url(),其中属性regex用于设置匹配规则,to_python()方法用于将匹配到的字符串转换成要传递到视图中的类型;to_url()方法用于将Python数据类型转换为URL模式中使用的字符串。16.1.2路由转换器自定义路由转换器定义完成之后,需要通过urls模块中的register_converter()函数将其注册到Django的路由系统。register_converter函数的格式如下:register_converter(converter,type_name)语法格式register_converter()函数中有两个参数,其中参数converter用于指定要注册的自定义路由转换器;参数type_name用于为自定义路由转换器指定一个唯一的名称,此名称会在URL模式中使用。16.1.2路由转换器2.自定义路由转换器(1)创建名称为chapter16的Django项目,在该项目中创建应用app01,并在项目的配置文件中激活app01应用,具体代码如下加粗部分所示:16.1.2路由转换器2.自定义路由转换器INSTALLED_APPS=["django.contrib.admin","django.contrib.auth","django.contrib.contenttypes","django.contrib.sessions","django.contrib.messages","django.contrib.staticfiles",'app01',](2)在chapter16项目的urls.py文件中配置根路由,具体代码如下加粗部分所示:16.1.2路由转换器2.自定义路由转换器fromdjango.contribimportadminfromdjango.urlsimportpath,includeurlpatterns=[path("admin/",admin.site.urls),
path('app01/',include('app01.urls')),](3)在应用app01中新建converter.py文件,在该文件中定义一个表示自定义路由转换器的类MyConverter,并通过register_converter()函数将自定义路由转换器注册到路由系统中。定义与注册自定义路由转换器的代码如下所示:16.1.2路由转换器2.自定义路由转换器fromdjango.urlsimportregister_converterclassMyConverter:regex='1[3-9]\d{9}'#匹配规则defto_python(self,value):#将匹配到的字符串转换成要传递到视图中的类型
returnvaluedefto_url(self,value):#将Python数据类型转换为URL模式中使用的字符串
returnvalueregister_converter(MyConverter,'mobile')
#注册自定义路由转换器(4)路由转换器定义好之后,在app01应用中新建子路由文件urls.py,在该文件中导入路由转换器所在的文件,即导入converter模块,然后配置子路由,使用自定义的路由转换器匹配mobile/后面的手机号码,具体代码如下所示:16.1.2路由转换器2.自定义路由转换器fromdjango.urlsimportpathfromapp01importviews,converterurlpatterns=[path('mobile/<mobile:phone_num/>',views.show_mobile)](5)在app01应用的views.py文件中,增加定义视图函数show_mobile()的代码,该函数的作用是将手机号码呈现在页面中,具体代码如下所示:16.1.2路由转换器2.自定义路由转换器fromdjango.httpimportHttpResponsedefshow_mobile(request,phone_num):returnHttpResponse(f'手机号码为:{phone_num}')(6)运行开发服务器启动chapter16项目,在浏览器中访问:8000/app01/mobile,页面效果如图所示。16.1.2路由转换器2.自定义路由转换器
先定一个小目标!掌握路由分发的方式,能够使用include()实现路由分发的功能16.1.3路由分发路由分发一个Django项目中会包含多个应用,并且每个应用可能有多个URL模式,如果将项目中所有的URL模式都保存在根URLconf中,那么URLconf势必会变得非常臃肿,不利于后期维护。为了解决上述问题,Django允许每个应用将URL封装到本应用的URLconf中,在根URLconf使用urls模块的include()函数将应用中的URLconf导入即可实现路由分发,这样的路由分发可以有效降低应用的URLconf与根URLconf的耦合度。16.1.3路由分发使用include()实现路由分发有两种方式,分别是引入应用URLconf和引入URL模式列表,关于它们的介绍如下。include(module)语法格式chapter16项目实现路由分发的方式是引入应用URLconf,这种方式其实将应用程序的URL配置文件作为参数传递给include()函数,这样不仅可以将不同应用程序的路由规则集中在各自的URL配置文件中,还可以提高代码的可维护性。引入应用URLconf的语法格式如下所示。16.1.3路由分发1.引入应用URLconfmodule:用于指定应用URLconf。在chapter16项目中创建及激活app02应用,在项目的根URLconf中使用include()函数引入app02应用的URLconf,具体代码如下加粗部分所示:16.1.3路由分发1.引入应用URLconffromdjango.contribimportadminfromdjango.urlsimportpath,includeurlpatterns=[path("admin/",admin.site.urls),path('app01/',include('app01.urls')),
path('app02/',include('app02.urls')),#引入app02应用的URLconf]在app02应用中创建urls.py文件,在该文件中定义与应用相关的URL模式,具体代码如下:16.1.3路由分发1.引入应用URLconffromdjango.urlsimportpathfromapp02importviewsurlpatterns=[path('test/',views.index),]为了验证以上方式是否成功实现路由分发,这里可以在app02应用的views.py文件中增加定义视图函数的代码,具体代码如下所示。16.1.3路由分发1.引入应用URLconffromdjangoimporthttpdefindex(request):returnhttp.HttpResponse('Routedistributionsuccessful!')除了引入应用URLconf外,还可以给include()函数传入包含URL模式的列表,通过引入URL模式列表的方式实现路由分发的功能。这种形式不需要在应用中自行创建urls.py,只需在项目的urls.py文件中使用include()函数添加额外的URL模式列表即可。引入URL模式列表的语法格式如下所示。16.1.3路由分发2.引入URL模式列表include(module)语法格式module:用于指定包含一个或多个path实例的列表。在chapter16项目的urls.py文件中添加URL模式列表,之后使用include()函数引入URL模式列表,具体代码如下加粗部分所示:16.1.3路由分发fromdjango.contribimportadminfromdjango.urlsimportpath,includefromapp02importviewsapp02_extra_patterns=[path('test02/',views.index),]urlpatterns=[……
path('app02/',include(app02_extra_patterns)),#引入URL模式列表]2.引入URL模式列表运行开发服务器启动chapter16项目,在浏览器中访问:8000/app02/test02/,可以看到页面中显示了信息“Routedistributionsuccessful!”,说明通过引入URL模式列表的方式成功实现了路由分发的功能。16.1.3路由分发2.引入URL模式列表
先定一个小目标!掌握向视图传递额外参数的方式,能够通过path()函数向视图传递额外参数16.1.4向视图传递额外参数向视图传递额外参数16.1.4向视图传递额外参数path()函数允许向视图传递额外参数,这些参数会存放在一个字典中,字典的键代表参数名,值代表参数值。使用path()函数的第三个参数可以向视图传递额外参数。例如,在app02应用的urls.py文件中增加URL模式,具体代码如下:path('blog/',views.blog,{'blog_id':3}),示例代码向视图传递额外参数16.1.4向视图传递额外参数当路由系统匹配到blog/时,会调用视图blog,并向该视图中传递值为3的参数blog_id。URL模式中向视图传递了额外参数,那么视图需要增加接收额外参数的形参。例如,在app02应用views.py文件中定义blog视图,具体代码如下:defblog(request,blog_id):returnhttp.HttpResponse(f'参数blog_id值为:{blog_id}')
先定一个小目标!熟悉反向解析URL的方式,能够通过reverse()函数实现反向解析URL的功能16.1.5反向解析URL在使用Django开发项目时,可以直接在代码中使用URL来定义视图函数的路由规则,但这种方式会导致URL与项目之间的耦合度较高。如果在urls.py文件中修改了某个页面的URL,那么相应的视图函数或模板也需要进行相应的修改。在维护或更新项目过程中,这种方式可能会引发错误。16.1.5反向解析URLreverse()函数Django提供了urls模块中的reverse()函数来实现反向解析。通过反向解析,Django服务器会根据视图函数或路由规则的命名来动态生成URL,直到实际访问时服务器才会获取具体的URL。reverse(viewname,urlconf=None,args=None,kwargs=None,current_app=None)语法格式viewname:必选参数,表示URL模式名称或可调用的视图。如果是URL模式名称,则应该是urls.py文件中的name属性。urlconf:可选参数,用于指定要使用的URLconf。默认情况下,Django会使用项目的根URLconf。args:可选参数,传递给URL的列表类型的参数。kwargs:可选参数,传递给URL的字典类型的参数。current_app:可选参数,表示当前视图所属的应用。reverse()函数中参数args与kwargs不能同时使用。16.1.5反向解析URLreverse()函数在app02应用的urls.py文件中定义URL模式,具体代码如下:urlpatterns=[path('url-reverse/',views.get_url,name='url'),]16.1.5反向解析URLreverse()函数在app02应用中的views.py文件中定义get_url()视图,该视图可在页面显示通过反向解析获得的URL地址,具体代码如下:fromdjango.shortcutsimportreversedefget_url(request):returnhttp.HttpResponse(f"反向解析的URL为:{reverse('url')}")在浏览器访问:8000/app02/url-reverse/后,页面效果如图所示。16.1.5反向解析URLreverse()函数模型16.2
先定一个小目标!掌握模型的定义与使用,能够根据需求定义模型和使用模型16.2.1模型简介模型简介在Django中,模型是以Python类的形式定义的,每个模型类对应一张数据表,模型类的每个属性对应数据表中的一个字段。模型类定义在应用的
models.py
文件中,并继承
models.Model
类。16.2.1模型简介16.2.1模型简介模型简介在chapter16项目中创建及激活app03应用,在该应用的models.py
文件中定义一个表示书籍信息的模型类,具体代码如下:fromdjango.dbimportmodelsclassBookInfo(models.Model):name=models.CharField(max_length=20,verbose_name="名称")pub_date=models.DateField(verbose_name="发布日期")read_count=models.IntegerField(default=0,verbose_name="阅读量")comment_count=models.IntegerField(default=0,verbose_name="评论量")is_delete=models.BooleanField(default=False,verbose_name="逻辑删除")def__str__(self):return模型简介模型类定义好以后需要映射到数据库,映射分为两步:生成迁移文件和执行迁移文件。从本质上看,生成迁移文件是通过ORM机制生成执行数据库操作所需的SQL语句,而执行迁移文件则是执行迁移文件中的SQL语句。16.2.1模型简介16.2.1模型简介1.生成迁移生成迁移文件的命令具体如下:pythonmanage.pymakemigrations命令格式16.2.1模型简介(1)chapter16项目默认使用的数据库是SQLite3,由于本书前面没有讲过SQLite3数据库,为了方便大家查询数据库,所以这里将SQLite3数据库换成MySQL数据库。在chapter16项目的settings.py文件中将默认使用的数据库修改为MySQL,具体代码如下所示:DATABASES={'default':{'ENGINE':'django.db.backends.mysql',#数据库引擎'HOST':'',#数据库主机名'PORT':3306,#数据库端口号'USER':'root',#数据库用户名'PASSWORD':'123456',#数据库密码'NAME':'heima'#数据库名}}1.生成迁移16.2.1模型简介(2)chapter16项目中使用了MySQL数据库以后,还需要确保当前的开发环境中已经安装了MySQLdb模块,用于连接MySQL数据库。由于虚拟环境first_env中还没有MySQLdb模块,所以这里还需要在虚拟环境中安装该模块,具体安装命令及其运行结果如下所示。(first_env)E:\env_space\chapter16>pipinstallmysqlclient==2.2.0……Installingcollectedpackages:mysqlclientSuccessfullyinstalledmysqlclient-2.2.01.生成迁移16.2.1模型简介(3)Django本身并没有提供创建数据库的功能,为了能保证chapter16项目能够正常连接到名称为heima数据库,这里需要通过其他方式提前创建该数据库,这里使用MySQL命令的方式创建数据库。以管理员身份打开命令行窗口中,在该窗口中通过命令切换到D:\programs\mysql-8.0.34-winx64\bin目录下登录MySQL,登录成功后在提示符后面输入创建数据库heima的命令,具体命令及其运行结果如下所示:1.生成迁移createdatabaseheimacharset=utf8;命令格式16.2.1模型简介(3)打开另一个命令行窗口,在虚拟环境first_env中切换至chapter16项目的根目录,在根目录下执行生成迁移文件的命令,生成迁移文件命令如下。1.生成迁移pythonmanage.pymakemigrations命令格式16.2.1模型简介迁移文件生成之后,需要使用执行迁移文件命令生成对应的数据表。执行迁移文件的命令具体如下:2.执行迁移文件pythonmanage.pymigrate命令格式执行上述命令后,命令行窗口中会显示一些迁移操作执行过程的提示信息,执行成功后会在数据库中会生成会以“应用名_模型类名(小写)”形式命名的数据表,比如app03应用下定义模型类BookInfo,会在heima数据库中生成数据表app03_bookinfo。
先定一个小目标!熟悉模型的字段,能够归纳常见字段的功能16.2.2模型的字段模型的字段16.2.2模型的字段字段是Django模型的重要组成部分,每个模型类的字段对应数据表中的一个字段。模型字段是模型类的属性,它自身也是一个类。模型中的字段分为字段类型和关系字段,字段类型用于定义字段的数据类型;关系字段用于定义模型之间的关联关系。1.字段类型16.2.2模型的字段在Django中,字段类型指的是在定义模型时,用于描述数据表中字段类型的类。Django内置了许多字段类,用于表示不同种类的数据。字段类说明AutoField用于定义可自增的整数字段BigAutoField用于表示一个可自增的大整数字段BooleanField用于定义布尔类型的字段,值为True或FalseCharField用于定义字符串类型的字段DateField用于定义格式为YYYY-mm-dd的表示日期字段FileField用于上传文件的字段,该字段不能作为主键ImageField用于上传图片类型文件,继承FileField,包含FileField字段的全部参数IntegerField用于定义整型字段,取值范围为-231~231-1TextField用于定义大文本字段2.关系字段16.2.2模型的字段关系型数据库不仅定义了数据的组织形式,还定义了表间的关系,因此Django中的模型除了要定义表示数据类型的字段,还需要定义表间关系。数据库表之间的关系分为一对多、一对一和多对多三种,Django使用ForeignKey、OneToOneField和ManyToManyField关系字段类来定义这三种关系。ForeignKey16.2.2模型的字段ForeignKey用于定义一对多关系,它包含两个必选参数to、on_delete,其中参数to指定与之关联的模型;参数on_delete用于设置关联对象删除后当前对象的处理方式,它的默认值为models.CASCADE,表示级联删除,也就是说删除主表中记录的同时也删除关联表中相关的记录。在定义一对多关系时,需要将ForeignKey字段定义在处于“多”的一端的模型类中。以国家和城市为例,一个国家包含多个城市,国家和城市之间具有一对多关系,ForeginKey应该定义在表示城市的模型类中。示例如下:fromdjango.dbimportmodelsclassCountry(models.Model): country_code=models.CharField(max_length=20)country_name=models.CharField(max_length=50)classCity(models.Model):city_name=models.CharField(max_length=20)city_area=models.IntegerField(default=0)city_nation=models.ForeignKey(Country,on_delete=models.CASCADE)16.2.2模型的字段ForeignKey16.2.2模型的字段OneToOneFieldOneToOneField用来定义一对一关系,它继承了ForeignKey,使用方式与ForeignKey类似。与ForeignKey不同的是,OneToOneField需要添加一个位置选项来指定与关联模型的关系。在定义一对一关系时,可将OneToOneField字段定义在任意模型类中。以国家和总统为例,一个国家只能有一个总统,一个总统也只能属于一个国家,将OneToOneField定义在表示总统的模型类中,示例如下:classPresident(models.Model):president_name=models.CharField(max_length=20)president_gender=models.CharField(max_length=10)president_nation=models.OneToOneField(Country)16.2.2模型的字段OneToOneField16.2.2模型的字段ManyToManyFieldManyToManyField用来定义多对多关系,它需要一个必选位置参数to,用于指定与当前模型关联的模型。与定义一对一关系类似,在定义多对多关系时,可将ManyToManyField字段定义在任意模型类中。以教师和学生为例,多位教师可以对应多名学生,定义具有多对多关系的教师表和学生表,示例如下:classTeachers(models.Model):name=models.CharField(max_length=10)classStudents(models.Model):name=models.CharField(max_length=10)classes=models.ManyToManyField(Teachers)16.2.2模型的字段ManyToManyField16.2.2模型的字段3.字段通用参数字段的一些参数为该字段的特有参数,但还有一些参数为多个字段的通用参数,常见的字段通用参数如表所示。参数说明null指定字段的数据库存储值是否可以为NULL,默认值是Falsedefault指定字段的默认值,默认值不能是模型实例、列表、集合等可变对象blank指定字段是否可以为空白,默认值是Falsechoices用于限制字段的值必须来自特定的预定义选项列表primary_key指定模型中的字段是否是主键,默认值是False,一般作为AutoField的参数使用unique指定字段在表中是否唯一,默认值是False
先定一个小目标!掌握数据的增删改查操作,能够通过objects管理器实现添加、查询、更新和删除数据的功能16.2.3数据的增删改查数据的增删改查Django为每个模型类添加一个名为objects的管理器(Manager),管理器提供了许多用于数据库查询和操作的方法。通过
objects
管理器可以执行各种数据库操作,基本操作包括添加数据、查询数据、更新数据和删除数据等。16.2.3数据的增删改查1.添加数据16.2.3数据的增删改查向数据表中添加数据有两种方式,一种方式是使用管理器的create()方法添加数据,另一种方式是使用模型实例的save()方法添加数据,关于它们的介绍如下。(1)使用管理器的create()方法添加数据create()是模型类管理器提供的方法,用于创建一个模型类对象,并将该对象保存至数据库中,实现添加数据的效果,其语法格式如下:create(self,**kwargs)语法格式**kwargs:参数需要接收一个或多个以关键字参数的方式传递的字段,其中关键字参数的名称为字段名,值为字段对应的值。1.添加数据16.2.3数据的增删改查导入app03.models的模型类,使用模型类BookInfo管理器的create()方法添加数据,具体代码及其运行结果如下所示:>>>fromapp03.modelsimport*>>>BookInfo.objects.create(name="骆驼祥子",read_count=100,...pub_date="1937-1-2",is_delete=0,comment_count=70)<BookInfo:骆驼祥子>1.添加数据16.2.3数据的增删改查(2)使用模型实例的save()方法添加数据save()方法是模型实例的方法,用于将模型实例中的数据添加到数据库中,其语法格式如下:save(force_insert=False,force_update=False,using=None,update_fields=None)语法格式force_insert:表示强制执行插入语句,不可与force_update同时使用。force_update:表示强制执行更新语句,不可与force_insert同时使用。using:用于将数据保存到指定的数据库。update_fields:用于指定更新的字段,其余的字段不更新。1.添加数据16.2.3数据的增删改查例如,创建模型类BookInfo的实例,通过该实例调用save()方法添加数据,具体代码如下所示:>>>bookinfo=BookInfo(name='围城',pub_date='1994-02-05',...read_count=134,comment_count=100,is_delete=0)>>>bookinfo.save()2.查询数据16.2.3数据的增删改查管理器提供了四个查询数据的方法:all()、filter()、exclude()和get()。16.2.3数据的增删改查(1)all()方法all()方法用于查询模型在数据库映射的表中的所有记录,返回值是一个QuerySet对象,该对象是一个类似列表的结构,它支持for循环、正索引、切片等操作。例如,使用all()方法查询模型类BookInfo所对应数据表中的所有记录,具体代码及其运行结果如下所示:>>>all_book=BookInfo.objects.all()>>>all_book<QuerySet[<BookInfo:骆驼祥子>,<BookInfo:围城>]>2.查询数据16.2.3数据的增删改查(2)filter()方法filter()方法用于根据查询条件查询数据表,查询条件的基本形式为“字段名称__运算符=值”,筛选出满足条件的数据,并返回一个QuerySet对象。例如,使用filter()方法查询id值小于2的记录,具体代码及其运行结果如下所示:>>>filter_book=BookInfo.objects.filter(id__lt=2)>>>filter_book<QuerySet[<BookInfo:骆驼祥子>]>2.查询数据16.2.3数据的增删改查2.查询数据常见的运算符如表所示。运算符说明gt判断字段值是否大于给定的值gte判断字段值是否大于等于给定的值lt判断字段值是否小于给定的值lte判断字段值是否小于等于给定的值in判断字段值是否存在于一个可迭代列表中range判断字段值是否在指定的区间中exact判断字段值是否精确相等16.2.3数据的增删改查2.查询数据常见的运算符如表所示。运算符说明iexact判断字段值是否精确相等,忽略大小写contains字段值的模糊匹配icontains字段值的模糊匹配,忽略大写startswith判断字段值是否以特定字符串开头istartswith判断字段值是否以特定字符串开头,忽略大小写endswith判断字段值是否以特定字符串结尾iendswith判断字段值是否以特定字符串结尾,忽略大小写16.2.3数据的增删改查(3)exclude()方法exclude()方法用于根据查询条件查询数据表,筛选出不满足条件的数据,并返回一个QuerySet对象。例如,使用exclude()方法查询id小于3的记录,具体代码及其运行结果如下所示:>>>exclude_book=BookInfo.objects.exclude(id__gte=3)>>>exclude_book<QuerySet[<BookInfo:骆驼祥子>,<BookInfo:围城>]>2.查询数据16.2.3数据的增删改查(4)get()方法get()方法用于根据查询条件进行查找,筛选出符合条件的一条记录,返回值是一个模型实例。例如,使用get()方法查询数据表books_bookinfo中id值为1的记录,具体代码及其运行结果如下所示:>>>get_book=BookInfo.objects.get(id=1)>>>get_book<BookInfo:骆驼祥子>2.查询数据16.2.3数据的增删改查delete()方法用于从数据表中删除数据,对应SQL中的删除操作,此方法会立即删除数据库中的记录,并返回删除记录的数量。例如,使用delete()方法从数据表books_bookinfo中删除记录get_book,具体代码及其运行结果如下所示:>>>get_book.delete()(1,{'app03.BookInfo':1})3.删除数据16.2.3数据的增删改查update()方法是QuerySet对象提供的方法,该方法将满足查询条件的记录的指定字段更新为新值,并返回被更新的记录数量。update()方法需要接收一个或多个关键字参数,用于指定要更新的字段和对应的新值。例如,将数据表中id为2的记录中is_delete字段的值修改为1,具体代码及其运行结果如下所示:>>>update_book=BookInfo.objects.filter(id=2).update(is_delete=1)>>>update_book14.更新数据模板16.3
先定一个小目标!掌握模板的配置,能够在项目中使用配置的模板16.3.1模板简介模板简介Django的模板是一个文本文件,这个文件可以是任何类型的,比如HTML文件、CSV文件、XML文件等,通常使用HTML文件作为模板。模板中可以定义网页的静态部分和动态部分,其中静态部分指的是HTML结构和布局,不受数据的影响;动态部分指的是嵌套在某个位置的模板语法,通过模板语法,可以将视图传递过来的数据动态地插入到模板中,并对数据进行处理和格式化,实现根据数据动态生成网页内容的目的。16.3.1模板简介模板简介Django项目通过模板引擎渲染模板,渲染模板其实是将模板文件与具体的数据结合起来,生成最终网页内容的过程。在这个过程中,模板引擎会解析模板文件,识别其中的静态部分,同时处理模板中的模板语法,并会根据视图函数传递的数据将模板语法替换为实际的内容。Django项目中可以配置一个或多个模板引擎。Django有内置的模板引擎,同时也支持广泛使用的Python模板引擎Jinja2。16.3.1模板简介若要在Django项目中使用模板,需要在settings.py文件的配置项TEMPLATES中提前配置模板引擎。TEMPLATES的值是一个列表,列表里面的每个元素对应一个引擎的配置。例如,chapter16项目中settings.py文件的配置项TEMPLATES默认代码如下所示:TEMPLATES=[{"BACKEND":"django.template.backends.django.DjangoTemplates","DIRS":[],"APP_DIRS":True,"OPTIONS":{"context_processors":[……],},},]16.3.1模板简介模板简介一个引擎通常需要指定四项信息:BACKEND、DIRS、APP_DIRS、OPTIONS,关于这四项信息的含义说明如下。(1)BACKEND:指定用于实现Django模板引擎API的模板引擎类的路径。Django内置模板引擎DjangoTemplates和Jinja2的路径分别为django.template.backends.django.DjangoTemplates和django.template.backends.jinja2.Jinja2。(2)DIRS:用于设置模板源文件的目录列表,模板引擎将按列表中元素的顺序依次查找目录中的模板文件。默认情况下,Django约定在项目根目录下的templates文件夹中查找模板文件,此文件夹需要用户单独创建,此时需要先导入os模块,再在目录列表中增加一个元素为os.path.join(BASE_DIR,'templates')。16.3.1模板简介模板简介一个引擎通常需要指定四项信息:BACKEND、DIRS、APP_DIRS、OPTIONS,关于这四项信息的含义说明如下。(3)APP_DIRS:声明是否在已安装的应用程序中查找模板,默认值为True。(4)OPTIONS:模板引擎的选项信息,它的值是一个字典,字典中可以包含多个键值对,用于指定模板引擎的各种选项。比如,content_processors用于指定上下文处理器列表,在渲染模板时将处理器中的数据添加到模板上下文中。16.3.1模板简介模板简介无论使用哪个模板引擎,Django都会采用统一的标准加载和渲染模板,加载模板的函数是get_template()和selsect_template(),它们被定义在django.template.loader模块中,其语法格式如下:16.3.1模板简介模板简介get_template()函数接收模板名称,返回Template对象;select_template()函数接收一个模板名称列表,它会按照顺序尝试加载列表中的模板,返回找到的第一个模板的Template对象。若没有找到模板,这两个方法都抛出TemplateDoesNotExist异常;若找到的模板中存在语法错误,则抛出TemplateSyntaxError异常。get_template()和select_template()函数的参数using是可选参数,用于接收模板引擎的名称,限定搜索时使用的模板引擎。get_template(template_name,using=None)select_template(template_name_list,using=None)语法格式get_template()和select_template()函数都会生成Template对象,该对象中提供了render()方法用于渲染模板。render()方法的语法格式如下:16.3.1模板简介模板简介context:表示要传递给模板的上下文数据,它的值是一个字典,字典的内容为在模板中使用的变量及其对应的值,可以为空。request:表示请求对象,它的值是一个HttpRequest对象。render()方法会返回一个字符串,表示成功渲染模板后的结果。render(context=None,request=None)语法格式
先定一个小目标!掌握模板,能够在项目中使用模板以及语法规则16.3.2模板语法模板语法模板文件包含静态部分和描述数据如何插入HTML的动态部分,模板语言分变量(variables)和标签(tags)两部分定义了这些动态内容的语法,此外,Django为变量定义了过滤器(filter),也支持自定义过滤器,以便模板可以呈现更加灵活的数据。16.3.2模板语法variable表示模板变量的名称,由字母、数字和下画线组成,但不能以下画线开头。16.3.2模板语法1.变量{{variable}}语法格式模板语言中的变量用于标识模板中会动态变化的数据,当模板被渲染时,模板引擎将变量替换为视图传递过来的真实数据。模板变量的基本语法格式如下:16.3.2模板语法1.变量通过点字符进一步访问变量中的数据,但由于模板不明确模板变量的类型,因此模板引擎会按以下顺序进行尝试。(1)将变量视为字典,尝试根据键访问其对应的值。(2)将变量视为对象,尝试访问对象的属性或方法。(3)尝试访问变量的索引。需要注意的是,若点字符后面是一个方法,则这个方法在被调用时不需要带括号。例如调用字典类型的变量books的items()方法,具体代码如下:{{books.items}}若变量不存在,则模板引擎将以string_if_invalid选项的值替换该变量,默认值为空字符串,这样可以保证模板在遇到不存在的变量时能够正常渲染。16.3.2模板语法2.过滤器{{variables|filters}}语法格式过滤器用于对变量进行处理和格式化,基本语法格式如下:variable表示模板变量的名称,filters表示过滤器,它们之间使用管道符号“|”连接。需要注意的是,管道符号和变量、过滤器之间不能有空格。还可以使用多个管道符号连接多个过滤器,连续对同一变量进行过滤,其语法格式如下。{{variables|filters1|filters2|...}}语法格式一些过滤器可以接收参数,过滤器与参数之间使用“:”分隔。若参数中含有空格,则参数必须放在引号之内,例如{{list|join:","}}。(1)addadd用于将过滤器的参数与变量的值进行相加操作,示例如下:16.3.2模板语法2.过滤器{{value|add:"32"}}当变量value的值为3时,则结果是35。add过滤器首先尝试将变量和参数都强制转换为整数,若转换失败,add会连接变量与参数。示例如下:{{first|add:second}}假设first值为[1,2,3],second的值为[4,5,6],则输出结果为[1,2,3,4,5,6]。需要注意的是,连接变量和参数的操作只适用于字符串或列表这种类型的数据,若为其它类型的数据,则会返回空字符串。(2)centercenter用于指定宽度,使变量的值居中显示,并在两侧填充指定的字符。示例如下:16.3.2模板语法2.过滤器{{value|center:"18"}}假设value的值为“itcast”,结果为“itcast”。(3)defaultdefault用于指定变量的默认值。如果变量未定义或者为空,则返回默认值。示例如下:{{value|default:"35"}}假设value的值为“”,则结果为“35”。(4)joinjoin用于将列表的所有元素以指定的分隔符连接成一个字符串。示例如下:16.3.2模板语法2.过滤器{{value|join:"//"}}假设value的值为[1,2,3],则结果将是字符串“1//2//3”。(5)lengthlength可返回变量的长度,可用于字符串和列表。示例如下:{{value|length}}假设value的值为[1,2,3],结果将是3。标签蕴含一定的逻辑,它的功能要比变量复杂,例如一些标签用于输出文本;一些标签通过执行循环或逻辑控制流;一些标签加载外部信息到模板中,以供后续变量的使用。标签格式简单,采用{%tag%}的形式进行标识;但也有一些标签必须成对出现,用于标识模板文本的开始和结束,示例格式如下:16.3.2模板语法3.标签{%tag%}...{%endtag%}示例(1)for循环遍历数组中的每个元素,以便在上下文变量中使用这些元素。模板语言中for的用法与Python中的for相同。例如,使用for标签遍历书单book_list,并输出所有书名,示例代码如下:16.3.2模板语法3.标签{%forbookinbook_list%}<li>{{}}</li>{%endfor%}模板中的for支持反向遍历列表,语法格式如下:16.3.2模板语法3.标签{%forobjinlistreversed%}语法格式若要遍历双层列表,可以解包内层列表中的每个元素到多个变量中。例如,列表points中的每个元素都是[x,y]形式的坐标,输出每一个坐标的x、y值,示例代码如下:{%forx,yinpoints%}Thereisapointat{{x}},{{y}}{%endfor%}需要注意的是,操作符“.”查找优先于方法查找,因此若字典中包含键items,data.items将返回data[‘items’]而非data.items()。如果想在模板中使用字典的方法,如items、values、keys等,需避免使用字典的方法名作为键名。16.3.2模板语法3.标签(2)ifif是条件判断标签,可以选择与elif、else搭配使用,它们与Python中关键字if、elif、else的含义相同。若满足判断条件,则会显示相应子句中的内容。示例代码如下:16.3.2模板语法3.标签{%ifbook_list%}现有闲余图书:{{book_list|length}}本{%elifbook_leased_list%}图书待归还……{%else%}没有图书{%endif%}if标签允许使用逻辑运算符and、or或not进行布尔测试,允许同一标签中同时使用and和or,and的优先级高于or。示例如下:16.3.2模板语法3.标签{%ifathlete_listandcoach_listorcheerleader_list%}需要注意的是,模板语言的if标签不支持括号,若需明确表示混合语句中子句的优先级,应使用if嵌套语句。if标签还支持运算符==、!=、<、>、<=、>=以及in、notin、is、isnot,示例代码如下:{%ifsomevar=="x"%}Thisappearsifvariablesomevarequalsthestring"x"{%endif%}示例示例视图16.4
先定一个小目标!掌握视图的定义,能够在Django项目中定义函数视图16.4.1视图简介视图简介视图用于处理HTTP请求,并返回响应。视图的功能决定了它的基本结构,具体如下:defview_name(request,*arg=None,**kwargs=None):代码段returnHttpResponse(response)语法格式16.4.1视图简介使用以上结构可以定义一个基本视图,显然这个视图本质上是一个Python函数。在上述结构中,view_name表示视图名称;参数request是必选参数,用于接收请求对象,即HttpRequest类的实例;参数args和kwargs为可选参数,用于接收URL中的额外参数;返回值用于返回响应对象,即HttpResponse类或其子类的实例。在app03应用的views.py文件中定义一个视图curr_time(),用于返回当前日期和时间,具体代码如下:(1)若要修改视图返回的页面样式,必须修改Python代码。(2)若页面内容较多,视图中的代码会变得非常臃肿。importtimedefcurr_time(request):current_time=time.time()local_time=time.localtime(current_time)now=time.strftime("%Y-%m-%d%H:%M:%S",local_time)response="<html><body>当前时间:%s</body></html>"%nowreturnHttpResponse(response)16.4.1视图简介视图简介Django提倡将页面样式放在模板文件之中,在视图文件中使用字典向模板传递数据。提取视图curr_time()中的样式代码,将这些样式代码全部放在新创建的time.html文件中,示例代码如下:模板的变量now表示当前时间,它接收从视图函数中传来的数据。下面修改views.py文件中视图函数的代码。<head><metacharset="UTF-8"><title>当前时间</title></head><body>当前时间:{{now}}</body>16.4.1视图简介视图简介修改views.py文件中视图函数的代码,修改后的代码如下:importtimedefcurr_time(request):current_time=time.time()
#获取当前时间local_time=time.localtime(current_time)now=time.strftime("%Y-%m-%d%H:%M:%S",local_time)context={'now':now}#上下文数据temp_obj=get_template("time.html")response=temp_obj.render(request=request,context=context)
#渲染模板,指定上下文数据returnHttpResponse(response)16.4.1视图简介视图简介
先定一个小目标!熟悉视图,能够归纳请求对象的常见属性和方法16.4.2请求对象请求对象16.4.2请求对象请求对象由Django自动创建,并由视图的request参数接收。Django项目中,几乎所有请求的处理都离不开请求对象。请求对象是HttpRequest类的实例,它封装了HTTP请求的所有信息。我们可以使用HttpRequest类定义的属性和方法访问与HTTP请求相关的信息。HttpRequest对象提供了很多属性,这些属性可以方便用户获取HTTP请求的各种信息,包括请求体、请求方法、请求资源的路径部分等。HttpRequest对象的常用属性如表所示。16.4.2请求对象HttpRequest的常用对象属性说明body用于获取原始HTTP请求的请求体信息,获取的结果是字节类型的数据path用于获取请求的路径部分,不包括域名和参数method用于获取本次HTTP请求所用的请求方法,常用在根据不同请求方法执行不同逻辑的场景GET获取包含GET请求参数的QueryDict对象POST获取包含POST请求参数的QueryDict对象COOKIES获取包含请求中的cookie信息的字典对象META获取包含请求头的字典对象(1)GET属性GET属性用于获取包含GET请求的所有参数,它的值是一个QueryDict对象。QueryDict对象与普通字典的功能类似,但它具有一些额外的功能和特性。若要获取特定参数的值,则可以使用QueryDict对象的get()方法进行获取。例如,通过request.GET.get(‘name’)获取参数name对应的值。(2)POST属性POST属性用于获取包含POST请求的所有参数,它的值是一个QueryDict对象。需要注意的是,如果用户以POST方式提交表单请求,但表单中没有数据时,服务器收到的POST请求将为空。因此,在判断是否使用了POST方法时,不能使用“ifrequest.POST”,而应使用“ifrequest.method=='POST'”进行判断。16.4.2请求对象HttpRequest的常用对象(3)META属性META属性用于获取包含HTTP请求头信息,该属性的值是一个字典,可以通过特定的键来访问其对应的值,以查看请求的各种附加信息,常用的键具体如下。CONTENT_LENGTH:请求正文的长度,按字符串类型计算。CONTENT_TYPE:请求正文的MIME类型。HTTP_REFERER:HTTP请求的来源页面的URL。HTTP_ACCEPT:可接收的响应内容类型。HTTP_ACCEPT_ENCODING:可接收的响应编码类型。HTTP_ACCEPT_LANGUAGE:可接收的响应语言类型。HTTP_HOST:客户端发送的HTTP主机头部信息。HTTP_USER_AGENT:客户端的UserAgent字符串。16.4.2请求对象HttpRequest的常用对象HttpRequest对象提供了很多方法,这些方法方便用户访问或操作HTTP请求的各种信息,包括获取请求的主机名、获取请求的端口号等。HttpRequest对象的常用方法如表所示。16.4.2请求对象HttpRequest的常用方法属性说明get_host()根据META属性中特定键HTTP_X_FORWARDED和HTTP_HOST的值,按顺序返回发起请求的原始主机名get_port()根据META属性中特定键HTTP_X_FORWARDED_PORT和SERVER_PORT的值顺序返回发起请求的端口号get_full_path()获取完整的请求路径,包括查询参数build_absolute_uri()根据HttpRequest对象中的相关信息构建一个绝对URLget_signed_cookie()用于获取已签名的Cookie的值,若签名不合法,则返回django.core.signing.BadSignture
先定一个小目标!16.4.3响应对象熟悉视图,能够归纳响应对象的常见属性和方法1.HttpResponse的常用属性HttpResponse对象提供了很多属性,通过这些属性用户可以方便地设置HTTP响应的各种信息,包括响应状态码、内容、字符编码等。16.4.3响应对象16.4.3响应对象1.HttpResponse的常用属性HttpResponse对象的常用属性如表所示。属性说明content用于设置响应消息的内容,值为字节类型的数据charset用于设置响应消息的字符编码方式。若不设置,Django将通过解析content_type获取编码方式;若解析失败,则使用默认值DEFAULT_CHARSETstatus_code用于设置响应的HTTP状态码reason_phrase用于获取与HTTP状态码对应的原因短语。除非明确设置该属性,否则该属性将通过status_code的值确定HttpResponse对象提供了很多方法,这些方法可以方便用户访问或操作HTTP响应的各种信息,包括设置Cookie信息、删除Cookie信息等。下面对一些常用方法进行介绍。(1)__init__()方法:__init__()是HttpResponse类的构造方法,该方法
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年中国天然气取暖市场调查研究报告
- 公文综合讲义(政工培训)-20143皇甫志辉
- 小学简笔画课程设计
- 大数据编程课程设计
- 锻造工艺学课程设计
- 传统磨豆腐课程设计
- 锅炉通风除尘课程设计
- 2024年中国减压器主体市场调查研究报告
- 中班汽车探究课程设计
- 3d打印玩具课程设计
- 手术室的人文关怀
- 2024年呼吸内科护理工作计划模版(4篇)
- (三级)工业机器人运用与维护理论考试复习题库(含答案)
- 农贸市场通风与空调设计方案
- 辅导员年度述职报告
- 医疗器械经营质量管理制度
- 2024年教师资格考试高级中学面试语文试题及解答参考
- 2024年广东省深圳市中考英语试题含解析
- 部编版小学五年级上册道德与法治单元检测试卷含答案(全册)
- 四年级英语上册 【月考卷】第三次月考卷(Unit 5-Unit 6) (含答案)(人教PEP)
- 2024-2030年分析仪器行业市场发展分析及发展趋势与投资研究报告
评论
0/150
提交评论