第六模块:WEB框架开发之Django框架开发学习笔记1蓝蓝的白云天!

WEB应用就是服务器上的程序,它接受客户端(浏览器)的请求,并响应请求发送字符串给客户端.

2.1socket套节字网络数据传输必须要用到socket,(其实本地电脑的应用程序和操作系统之间也需要socket)

2.2实例:一个简单的WEB应用程序

#一个简单的WEB应用程序importsocketsock=socket.socket()sock.bind(("127.0.0.1",8800))sock.listen(5)while1:print('serverwaiting......')conn,addr=sock.accept()data=conn.recv(1024)print('data',data)#conn.send(b"helloluffycity")#用浏览器访问时,显示该网页无法正常运作127.0.0.1发送的响应无效。ERR_INVALID_HTTP_RESPONSE.因为浏览器无法识别发过来的数据.conn.send(b"HTTP/1.1200OK\r\n\r\nhelloluffycity")#规范的WEB请求格式,浏览器的页面可以正常显示了.conn.close()一个简单的WEB应用程序三.WEB应用程序23.1发送字符串,让浏览器渲染出带html标签

的字符串

3.2WEB应用程序读取html文件,并发送到客户端,客户端浏览器进行渲染

4.1包含以下三个部分:

(每一个小块数据用\r\n区隔开)

a.请求首行包含:请求方式(get或post)请求路径(url)协议(HTTP/1.1)

b.请求头(若干个键值对)常包含:HostConnectioncontent-Type等

c.请求体连续两个\r\n后的就是请求体只有post请求才有请求体,get请求没有请求体

4..2请求数据实例

GET/HTTP/1.1\r\nHost:127.0.0.1:8899\r\nConnection:keep-alive\r\nUpgrade-Insecure-Requests:1\r\nUser-Agent:Mozilla/5.0(WindowsNT6.1;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/86.0.4240.75Safari/537.36\r\nAccept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nSec-Fetch-Site:none\r\nSec-Fetch-Mode:navigate\r\nSec-Fetch-User:1\r\nSec-Fetch-Dest:document\r\nAccept-Encoding:gzip,deflate,br\r\nAccept-Language:zh-CN,zh;q=0.9\r\n\r\n'ViewCode

4.3get与post的使用区别

get一般应用于查询,post应用于更新数据库数据

只有POST请求才有请求体

服务器的接收到的请求(末尾黄色字是请求体,即浏览器用户输入的用户名和密码):

一个典型的服务器端post请求源代码

-get提交的数据会放在URL之后,以分割URL和传输数据,参数之间以&相连,如EditBookname=test1&id=123456.POST方法是把提交的数据放在HTTP包的请求体中.

-get提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.

-get与post请求在服务端获取请求数据方式不同.

6.2响应格式(浏览器接收到服务器发来的信息)

6.3自定义响应头(黄色字符部分)

conn.send(b"HTTP/1.1200OK\r\nContent-Type:text\r\n\r\n%s"%data)

6.4响应状态码

状态码如200OK,以3位数字和原因成。数字中的一位指定了响应别,后两位无分。响应别有以5种。

重定向的解释:浏览器向服务器发送请求,服务器接收到后再发送响应信息给浏览器,该响应信息告诉浏览器需要(浏览器再发一次请求)转到另外一个资源.

-wsgi是接口协议

7.1wsgiref模块功能

-按照HTTP请求协议格式进行解包(解析数据)

-按照HTTP响应协议封装数据

-wgiref模块封装了socket

-让WEB应用开发者专注于WEB业务开发

-wsgiref做的简单的,根据用户不的输入,实现不同网页的效果

-路由的解释

9.1浏览器默认会发送图标请求

-此响应时,浏览器只接收图片,如果发送字符串,则字符串不会显示.

-其实也是解了耦合

增添功能,只需要修改路由文件,视图文件,模板等就可以了.

如果没有数据库,就没有什么意义.

大而全,组建特别多

14.1mvc和mtv模型(模型的主要目的是解耦合)

15.1cmd纯命令行,安装Django模块命令

pipinstallDjango#注意:Django首字母大写

如果提示pip错误,则先python.exe-mpipinstall--upgradepip,注意该命令前面不能带路径

15.2cmd纯命令行,在当前文件夹下创建一个mysite项目

django-admin.pystartprojectmysite#注意首字母d是小写

项目的文件夹树,manage.py为启动文件,相当于之前的main.py

manage.py----Django项目里面的工具,通过它可以调用djangoshell和数据库

settings.py----包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量

urls.py----负责把URL模式映射到应用程序

15.3cmd纯命令行,在mysite目录下创建应用blog(注意:mysite是项目文件夹,blog是应用程序文件夹,一个项目中可以包含多个应用程序)

首先cdmysite文件夹,进入sysite项目根目录

然后pythonmanage.pystartappblog创建blog应用程序

下图为创建blog应用后的文件夹

下图为blog应用程序的文件结构

15.4cmd命令下,启动Django项目

pythonmanage.pyrunserver8000

16.1.1创建一个Django项目

16.1.2生成的一个fisrt_pro项目,新建一个app01程序的目录

16.1.3几个文件的代码

16.2Django服务(请求)执行过程(MPV过程)

---->1.urls.py(由它决定用户发送的路径交给哪个视图函数处理)---->2.views.py(主要逻辑处理)---->3.models.py(涉及到数据库的从这里取)---->4.timer.html(最终的返回页面的模板)---->

17.1什么叫静态文件

项目中的css,js都应当处理为静态文件.项目中的任何文件都需要Django去找,最终都是由客户端的浏览器去执行的,引入jquery-3.1.1.js时就需要注意文件路径问题(不能当成客户端的本地文件去执行),js文件需要写成服务器的地址.

17.2如何配置静态文件

在项目的根目录下创建static文件夹,所有静态文件都放入其中.此时通过客户端浏览器无法直接访问该文件,因为(Django采用虚拟文件夹的方式访问)客户端的所有访问路径都经过urls.py路由处理,而urls.py中没有添加关于js的路由.在settings.py中配置一下就可以通过别名访问了.配置方法在下面.

处理settings.py文件

STATIC_URL='/static/'#路径别名(虚拟目录),客户端浏览器输入地址(路径)可直接访问了STATICFILES_DIRS=[os.path.join(BASE_DIR,'statics'),#实际路径,这里是方便为了区分才使用statics这个名字,正式使用时,实际目录和别名都用static]模板文件引入jquery-3.5.1.js,文字点击变为红色效果timer.html

18.1html文件中引入css和js

css文件和js文件也是静态文件,需要放到项目中的static文件夹下,针对不同的应用可以在static文件夹下再建立应用的子文件夹,比如app01,将app01应用程序的css和js文件放到app01文件夹下.这里需要注意的是,在html中引入css\js文件时需要使用static静态目录.

文件目录如下:

19.1re_path模块,Django1版本的路由

路由配置:路径-------->视图函数

采用正则表达式re匹配路径,(路径中加括号的分组)

fromdjango.shortcutsimportrender,HttpResponse#HttpResponse#Createyourviewshere.deftimer(request):importtimectime=time.time()returnrender(request,'timer.html',{'ctime':ctime})defspecial_case_2003(request):returnHttpResponse("special_case_2003")defyear_archive(request,year):returnHttpResponse(year)defmonth_archive(request,year,month):returnHttpResponse(year+"-"+month)defarticle_detail(request,year,month,date):returnHttpResponse(year+"-"+month+"-"+date)视图View.py

19.2注意:

-若要从URL中获取一值,只需要在它周围放置一对圆括号.

-不需要添加一个前导的反斜杠,应为每个URL都有.例如,应该是^articles而不是^/articles.

-每个正则表达式前面的"r"是可选的,但建议加上.它告诉python这个字符串是"原始的"----字符串中任何字符都不应该转义.

20.1为路径中的分组起名字,关键字参数传参

全局urls.py和一个app应用程序的urls.py,文件结构

21.2两个URLS.py代码

全局urls.py中的关键代码

第二次是在login页面点击提交按钮,这是POST请求

#'django.middleware.csrf.CsrfViewMiddleware',

23.1用别名指代URL.在模板中进行反向解析

urls.py中,对于路径采用别名.应用场景:当产品经理要求更改访问路径的时候,只需要改urls.py中的路径名就可以了,其它文件无需改动.

使用urls.py中使用别名,增加参数name='别名',注意在模板文件中把action中的路径改为规定的格式{%url"别名"%}.views.py中的函数名称与别名要保持一致.

24.1在视图函数中进行反向解析

可以在后台获取到用户访问的完整路径

需要在视图函数中导入反向解析函数reverse,需要注意的是,如果urls.py路径中包含正则表达式,则需要在视图函数中增加args参数

/app/articles/2005/

25.1名称空间(namespace),也叫命名空间,是表示标示符的可见范围.

由于name没有作用域,Django在反解析URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,立即返回,我们在开发项目时,会经常使用name属性反解除URL,当不小心在不同的app的urls中定义相同的name时,可能会导致URL反解错误,为了避免这种事情发生,引入命名空间.

25.2实例

25.2.1使用pycharm的命令行窗口创建新应用app02

25.2.2创建新应用后的目录如下:

25.2.3为全局urls.py添加app02的路由分发

fromdjango.contribimportadminfromdjango.urlsimportpath,re_path,includefromappimportviews,urlsurlpatterns=[re_path(r'^app/',include("app.urls")),#分发到app中re_path(r'^app02/',include("app02.urls")),#分发到app02中]全局urls.py文件25.2.4为app02增加index视图

fromdjango.shortcutsimportrender,HttpResponse#Createyourviewshere.defindex(request):returnHttpResponse("index2")app02的views.py25.2.5为app02的urls.py增加index的路由解析

25.2.7为app应用添加index视图和路由,以及访问的效果.

25.2.8分别为app和app01下的两个index加别名

应用程序中的urls.py文件中路由解析

re_path('index/',views.index,name='index')

现在就有两个index,名字就重复了.

25.2.9两个index,反向解析,就出问题了.

先分别为两个app的views.py添加名称index的反向解析reverse('index')

分别访问两个index,反向解析路径,得到的路径是相同的,就出问题了.(覆盖了)

25.2.10下面解决名称相同,的反向解析相同的问题

25.2.11在全局urls.py中给include()路由分发添加名称空间namespace

urlpatterns=[path('admin/',admin.site.urls),path('timer/',views.timer),re_path('login.html',views.login,name='login'),re_path(r'^app/',include(("app.urls","app"))),#名称空间namespace="app"注意这里增加了一个元组re_path(r'^app02/',include(("app02.urls","app02"))),#名称空间namespace="app02"]全局urls.py25.2.12再给两个app的views.py文件中的反向解析添加上namespace的名称

27.1django2.0的path.re_path是django1.0版本的语法

re_path传的值是字符串,如果要使用数字,还需要进行转换.path方法就是解决这类问题而生的.

urlpatterns=[path('admin/',admin.site.urls),path('timer/',views.timer),path('login/',views.login),path("articles/",views.path_year),#path_year(request,2001)]全局urls.py

27.2path的5个转化器

str,匹配除了路径分隔符/之外的非空字符串,这是默认的形式

int,匹配正整数,包含0

slug,匹配字母,数字以及横杆,下划线组成的字符串

uuid,匹配格式化的uuid,如075194d3-6885-417e-a8a8-6c931e272f00

path,匹配任何非空字符串,包含了路径分隔符

28.1对于一些复杂或者复用的需要,可以定义自己的转化器.转化器是一个类或接口,它的要求有三点:

28.2自定义path转化器应用实例.(使用register_converter将其注册到URL配置中)

29.2有名分组按关键字传参

29.3分发include

29.4反向解析利用别名

29.5名称空间

29.6path

30.1在视图函数中获取用户的请求数据

先关闭settings.py中的一项设置项目才可正常运行

获取到的get请求数据,是个字典格式.

获取值:

request.GET.get("name")request.POST.get("name")

re_path("^$",views.index)或者path(r"",views.index),

30.3方法request.get_full_path(),获取完成的路径可保护get数据

下面来看看两个区别:

print(request.path)#只能获取路径

print(request.get_full_path())#路径+get请求的数据

后台显示结果:

31.1最终都是返回HttpResponse(),render()也会转化为HttpResponse()

31.1.1HttpResponse("

ok

")

31.1.2render(request,"index.html",{"变量名":变量值})#把变量传递给模板,注意书写字典格式

模板文件index.html中使用{{变量名}}#模板语法,注意书写格式,双大括号

32.1字典,列表,对象,字符串,等更丰富的数据类型怎么嵌入到模板中

模板语法:渲染变量用{{}}用句点符深度查询,过滤器

渲染标签用{%%}

使用句点符达到的效果就是从字典,列表等数据中再获取指定位置的值

把视图中的变量按照某种形式在模板中渲染出来

33.1语法:

{{obj|filter_name:param}}33.2日期过滤器date

视图文件代码:

importdatetime

date=datetime.datetime.now()

模板文件代码:

{{date}}

显示效果:Jan.17,2021,1:06p.m.(显示的不友好)

{{date|date:'Y-m-d'}}

显示效果:2021-01-17这里date|date,两个date后面一个date是过滤器名称

下图为显示效果对比:

33.3default过滤器,默认在数据为空的情况下的显示内容

视图文件代码:name_list=[]列表值为空

模板文件代码:

{{name_list}}

显示效果:[]

{{name_list|default:"姓名数据为空"}}

显示效果:姓名数据为空

33.4length过滤器,返回值的长度

{{value|length}}如果value是['a','b','c'],那么输出是3

33.5filesizeformat,将值格式化为一个"人类可读"文件尺寸.主要用于显示文件的大小

{{value|filesizeformat}}如果value是123456789,输出将会是117.7MB

33.6slice过滤器,将字符串切片

{{value|slice:"2:-1"}}如果value="helloword",将输出llowor

33.7truncatechars,截断过滤器,如果字符串字符多余指定的字符数量,那么会被截断.截断的字符串将以可翻译的省略号序列"..."结尾

{{value|truncatechars:9}}参数9,就是要显示(截断)的字符数包含...一共是9个字符,(注意一个字母就是一个字符)

{{hello_str|truncatewords:1}}truncatewords参数3,表示显示的单词数量,不包含...(注意hello表示一个单词)

下图为显示效果:

33.8safe过滤器,强调不转义,用在变量是html标签时

33.9add加法过滤器

{{l.0|add:100}}如果l.0=100,那么输出200

33.10upper转大写过滤器

{{name|upper}}如果name="hao",那么输出HAO

34.1标签看起来像这样的:{%tag%}.标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模板中.一些标签需要开始和结束标签(例如{%tag%}...标签内容...{%endtag%})

34.2最少需要掌握for标签和if标签

34.3for循环标签

遍历每一个元素:

{%forpersoninperson_list%}

{{person.name}}

{%endfor%}可以利用{%forobjinlistreversed%}反向完成循环。

遍历一个字典:

{%forkey,valindic.items%}

{{key}}:{{val}}

{%endfor%}如果{%forkeyindic%}则只遍历key

注:循环序号可以通过{{forloop}}显示

34.4for...empty数据为空时的处置.为空的时候不会渲染.当使用for...empty时就可以渲染指定的内容.

for标签带有一个可选的{%empty%}从句,以便在给出的组是空的或者没有被找到时,可以有所操作。

{%forpersoninperson_list%}

{{person.name}}

{%empty%}

sorry,nopersonhere

{%endfor%}34.5if标签

{%if%}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。

34.6with标签,把长名字缩减成短名字

{%withperson_list.1.nameasn%}

{{n}}使用n就相当于用person_list.1.name,当深度查询非常长的时候用

{%endwith%}

使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的

例如:

{%withtotal=business.employees.count%}{{total}}employee{{total|pluralize}}{%endwith%}34.7csrf_token这个标签用于跨站请求伪造保护

此功能与全局settings.py中的'django.middleware.csrf.CsrfViewMiddleware'有关系

在表单的post提交中会出现下面的提示Forbidden(403):

如果在模板中添加csrf_token就不会出现Forbidden(403)错误了.

{%csrf_token%}查看网页源代码,多出了一个input标签,多出了的input就是{%csrf_token%}的功劳.有了它就可以正确提交post请求.(识别是不是第二次访问,拦截判断用)

34.1自定义标签与过滤器,流程固定,背下来

1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.

2、在app中创建templatetags模块(模块名只能是templatetags)

3、创建任意.py文件,如:my_tags.py

4、在使用自定义simple_tag和filter的html文件中导入之前创建的my_tags.py

5、使用simple_tag和filter(如何调用)

注意:filter可以用在if等语句后,simple_tag不可以

34.2实例自定义乘法过滤器

34.2.1在settings.py中配置app

34.2.2在app中创建templatetags模块(模块名只能是templatetags)

34.2.3创建my_tag_filter.py文件,目录如下:

fromdjangoimporttemplateregister=template.Library()@register.filterdefmulti_filter(x,y):#自定义乘法过滤器returnx*y34.2.4在使用自定义multi_filter的html文件中导入之前创建的my_tag_filter.py

{%loadmy_tag_filter%}34.2.5使用自定义multi_filter(如何调用)

36.1{%include'advertise.html'%}在html模板文件中嵌入其它html模板文件

两个父子模板文件在目录中的位置

在index.html文件中的左侧嵌入advertise.html

advertise.html文件全部代码

最终效果,左侧三个面板为{%include'advertise.html'%}嵌入的内容:

建立一个新页面order.html该页面想和前面的index.html拥有相同的头部和左侧面板,这就用到了继承.

新建base.html基础模板页面,作为父页面,复制index.html中的内容到该业中,该页面中,包含css,头部和左侧面板,内容部分被删除,代替以block盒子{%blockcon%}在这个中间加入该页面独特内容{%endblock%},代码如下:

{#继承自base.html,包含头部,左侧等内容#}{%extends'base.html'%}{%blockcon%}{#index.html页面独特的内容#}

首页内容区域

首页内容区域

首页内容区域

首页内容区域

首页内容区域

首页内容区域

首页内容区域

首页内容区域

{%endblock%}index.html新建订单页面orders.html,继承base.html页面,

{%extends'base.html'%}{%blockcon%}

订单页面

订单页面

订单页面

订单页面

订单页面

订单页面

订单页面

{%endblock%}orders.html可以在base.html页面中留多个盒子,甚至标签都可以设计为一个盒子.下面的代码是增加了一个控制标题的盒子{%blocktitle%}.模板页面中可以添加多个盒子,以解决代码复用的问题.

36.4注意事项

37.1Django的几大部分

url控制器,视图部分,模板部分,模型层

37.2模型层用于和数据库打交道.ORM就是用来控制数据库的.

ORM直接把python中的类转换为(翻译)mysql语句,以后我们直接编写Python类就可以控制数据库了.

注意ORM只能对表做操作,不能对库做操作.

38.1使用pycharm创建app01和orm数据库的Book表

38.1.1使用pycharm新建orm项目app01应用程序,使用cmd命令行创建orm数据库

cmd下连接mysql,进入mysql命令提示符,输入创建orm库的命令,完成数据库创建.

createdatabaseorm;

38.1.2在orm文件夹下的settings.py中修改DATABASES数据库设置如下:

importpymysqlpymysql.version_info=(1,4,13,"final",0)#防止Django版本引起错误pymysql.install_as_MySQLdb()orm下__init__.py文件中添加pymysql模块38.1.4在app01应用程序目录下的models.py文件中建立表的结构

pythonmanage.pymakemigrations#依照models.py中的类创建出表,创建迁移表

pythonmanage.pymigrate#迁移

38.1.6创建出的表,查看效果如下:

38.1.7如果想在orm转换过程中把对应的sql语句输出在后台,需要在settings中进行如下配置:

LOGGING={'version':1,'disable_existing_loggers':False,'handlers':{'console':{'level':'DEBUG','class':'logging.StreamHandler',},},'loggers':{'django.db.backends':{'handlers':['console'],'propagate':True,'level':'DEBUG',},}}ViewCode

39.1ORM主要用于增删改查数据记录

两种方法,一种是实例化类,一种的类的.objects.create方法

fromdjango.shortcutsimportrender,HttpResponsefromapp01.modelsimportBook#引入创建的表的类#Createyourviewshere.defindex(request):#添加表记录方法一#book_obj=Book(id=1,title='python红宝书',price=100,pub_date='2012-12-12',publish='人民出版社')#实例化Book对象#book_obj.save()#实例化对象的方法时,只有save一下数据才会保存到数据库中#添加表记录方法二book_obj=Book.objects.create(title='linux从入门到精通',price=80,pub_date='2013-01-25',publish='人民邮电出版社')#此种方法无需再用saveprint(book_obj.title)#.objects方法创建的,带有返回值,可以将值打印出来.print(book_obj.price)print(book_obj.pub_date)print(book_obj.publish)returnHttpResponse("ok")app01下的views.py

40.1单表查询接口,需要了解清楚的

QuerySet数据类型,Django特有的数据类型,该类型有点像列表,可以想列表一样来处理QuerySet,支持索引,支持for循环

弄清楚查询表的接口的,1每个方法的返回值2以及每个方法是谁来调用的

在app01下的models.py中的Book类中添加def__str__(self)方法用于print打印指定的数据

#app01下的models.pyfromdjango.dbimportmodels#Createyourmodelshere.classBook(models.Model):id=models.AutoField(primary_key=True)title=models.CharField(max_length=32)pub_date=models.DateField()price=models.DecimalField(max_digits=8,decimal_places=2)publish=models.CharField(max_length=32)def__str__(self):#此处功能是,在执行print命令时显示对象的titlereturnself.titleapp01下的models.py

40.2all方法:返回值是一个queryset对象,该方法由Book.objects管理器直接调用

all方法返回全部数据,all方法源代码:

fromdjango.shortcutsimportrender,HttpResponsefromapp01.modelsimportBook#Createyourviewshere.defindex(request):#查询表记录,all方法book_qs=Book.objects.all()print(book_qs)print('-')#遍历forobjinbook_qs:print(obj.title,obj.price)#输出书名,和价格print('-')#索引访问print(book_qs[1].title)#输出第二本书书名returnHttpResponse('OK')app01下的views.py后台输出效果:

40.3firsh,last方法,调用者是queryset对象,返回值是一个model对象

#查询记录,first,last方法,调用者是queryset对象,返回值是一个model对象book_obj=Book.objects.all().first()book_obj=Book.objects.all()[0]#和上面的等价book_obj=Book.objects.last()ViewCode40.4filter()筛选(过滤),根据条件筛选,返回值:queryset对象.该方法与all()方法类似.filter()方法也可以调用first()方法

#查询记录,filter()筛选,返回:queryset对象#filter()与all()的差别就是多个筛选条件,别的都一样.book_list=Book.objects.filter(price=80)#筛选出价格是80的所有记录print(book_list)#[obj1,obj2,...]book_obj=Book.objects.filter(price=80).first()ViewCode40.5get()有且只有一个查询结果时才有意义,有多个结果或没有查到时会报错.返回值:models对象

#查询记录,get()有且只有一个查询结果时才有意义,返回值:model对象book_obj=Book.objects.get(price=100)#book_obj=Book.objects.get(price=80)#因为有两本书价格是80,所以浏览器上会显示报错信息print(book_obj.title)ViewCode40.6本节app01下的views.py完整代码,包含上面4个常用的查询方法

41.1exclude()排除,方法,相当于!=不等于,所有符合条件的,然后取反.与filter()方法相反.注意:可以设置多个条件(多个条件是与的关系)

返回值是一个queryset对象,该方法由Book.objects管理器直接调用

#exclude()排除,返回值是:queryset对象.调用者:Book.objects管理器book_list=Book.objects.exclude(title='php',price=80)#可以设置多个排除条件,多个条件是与关系,也就是同时满足.filter()方法也是可以设多个条件的.print(book_list)ViewCode41.2order_by()排序,调用者:queryset对象,返回值:queryset对象

#order_by()排序ret=Book.objects.all().order_by('id')#按ID升序排列ret=Book.objects.all().order_by('-id')#条件前面加负号,按ID降序排列ret=Book.objects.all().order_by('price','id')#先按照price排序,如何price一样,则按照id排序print(ret)ViewCode41.3count()计数,调用者:queryset对象,返回值:int类型

#count()ret=Book.objects.all().count()print(ret)ViewCode41.4exist()判断表是否为空,调用者:queryset对象,返回值:布尔值True,False

#exist()判断是否为空#ret=Book.objects.all()#这种判断是否为空的方法太消耗资源(执行查询全部数据)ret=Book.objects.all().exists()#exists()方法只查询表中的一条记录,所以节约资源ifret:print('ok')ViewCode41.5queryset对象支持链式,多个方法串起来

42.1values()方法,获取对象中每个元素的值,输出列表套字典,返回值:queryset类型,调用者:queryset类型

ret=Book.objects.all().values("price")#values方法获取每个元素的值,默认可以省略all(),写成Book.objects.values("price")print(ret)print(ret[0].get('price'))#输出:"""valuers()方法的工作原理temp=[]forobjinBook.objects.all():temp.append({'price':obj.price}):returntemp"""ViewCode42.2values_list()方法,类似values()方法,输出的是列表套元组,返回值:queryset类型,调用者:queryset类型

#values_list()方法ret=Book.objects.all().values_list('price')#这里只演示了一个price字段,可以有多个字段,values()方法也可以有多个字段print(ret)#输出:ViewCode42.3distinct()去重,配合values(),values_list()方法使用.返回值:queryset类型,调用者:queryset类型

#distinct()去重,返回值:queryset类型,调用者:queryset类型ret=Book.objects.all().values('price').distinct()#获得图书的价格,去除相同价格的.print(ret)#输出:ViewCode42.4reverse():对查询结果反向排序.返回值:queryset类型,调用者:queryset类型

注意该方法需要配合order_by()方法使用,该方法是个鸡肋.这个方法只有在已经定义顺序的queryset上调用,才能对结果反向排序

#reverse()反向排序,鸡肋方法,没什么鸟用.ret=Book.objects.all().filter(price=80).order_by('id')ret2=Book.objects.all().filter(price=80).order_by('id').reverse()print(ret)print(ret2)ViewCode

42.4queryset对象支持链式,多个方法串起来

Book.objects.all().filter().order_by().filter().reverse().first()

大于小于的时候就需要用模糊查询,用双下划线.注意得到的仍然是queryset类型

43.1参数price__gt=80表示价格大于80

参数price__lt=200表示价格小于200

ret=Book.objects.filter(price__gt=80,price__lt=200)#查询价格大于80,且小于200的图书print(ret)ViewCode43.2参数title__startswith='py'表示标题以py开头的

参数title__contains='h'表示标题中包含字母h的

参数title__icontains='h'表示标题中包含字母h的,不区分大写

ret=Book.objects.filter(title__startswith='py')#查询书名以py开头的所有书ret=Book.objects.filter(title__contains='h')#查询书名中包含h的所有书ret=Book.objects.filter(title__icontains='h')#查询书名中包含h的所有书,不区分大小写print(ret)ViewCode43.4参数price__in=[80,100,200]表示只要是价格等于80或100或200

参数price__range=[80,100]查询价格在80到100之间的,包含80和100

ret=Book.objects.filter(price__in=[80,100,200])#查询只要是价格等于80或100或200的ret=Book.objects.filter(price__range=[80,100])#查询价格在80到100之间的,包含80和100print(ret)ViewCode43.5参数pub_date__year=2018查询日期是2018年的,月份和日随意,只有日期类型有此参数

参数pub_date__month=5查询月份是5月的.

ret=Book.objects.filter(pub_date__year=2021,pub_date__month=1)#查询年份是2018且月份是1月的print(ret)ViewCode43.6不止以上的这些个参数哦

44.1delete()方法,删除记录.返回值是删除的数据条数

delete()方法的调用对象是queryset对象,model对象也可以调用它.

#删除记录#ret=Book.objects.filter(price=100).delete()#queryset对象调用delete()#print(ret)#返回值:(1,{'app01.Book':1})Book.objects.filter(price=80).first().delete()#model对象调用delete()ViewCode44.2update()方法,修改记录.update()的调用者只能是queryset对象.

#修改记录Book.objects.filter(title='PHP').update(title='php零基础入门')#注意,筛选出多少条记录,就会修改多少条.返回值是条数ViewCode

系统功能简介:可以新建图书,查看图书数据,删除图书,修改图书信息.

1.建立数据库的表结构,即在models.py文件中设计Book表的结构,只要创建一个pythonBook类就可以了.

2.迁移数据库,即通过pycharm底部Terminal的,输入两条迁移命令.这里数据库使用了Django的默认sqlite3数据库.迁移完成后能看到在根目录中创建了db.sqlite3的数据库文件,pycharm窗口的的右侧可以打开查看db.效果如下,book表结构清晰可见:

3.由于本系统需要用到bootstrap等,所以需要对文件目录进行修改

3.1新增静态目录(包)static,用于存放bootstrap,在settings.py中增加static的设置

3.2复制bootstrap到static目录中

4.由于数据库中暂时没有数据,所有,下面,进行'新增图书'的设计.

4.1建立'新增图书的'路由设置

4.2建立'新增图书'的视图创建

4.3创建'新增图书'的模板,注意在表单部分的最前面增加{%csrf_token%},防止跨域403错误

模板注意使用class="container"制作外框,class="row"class="col-md-6col-lg-push-3(右移3)"建立模型

5.所有'图书'信息查看的设计,基本步骤和4一致.注意图书出版日期的显示{{book.pub_date|date:'Y-m-d'}}

6.'删除'功能.注意.注意路由设计re_path(r'books/(\d+)/delete/',views.delbook),

7.修改功能,注意点和6一样

8.完整代码:

51.1多表,为啥要用多个表

避免存储大量重复数据.把大表拆成多个表.

51.2一对多表,一个出版社对应多本书.

51.3总结:一旦确定表关系是一对多:创建关联字段,上图的publish_id是关联字段,创建关联字段要在多的表中

52.1多对多表,一本书对应多个作者,一个作者对应多本书.

52.2总结:一旦确定表关系是多对多:要创建第三张关系表,如上图Book2Author

53.1一对一表,本质是把一张表中的几个字段抽离出来组建一个新表.

一对多与一对一的差别.一对一的关联字段加上unique约束.关联字段放在哪张表都可以.

53.2总结:一旦确定是一对一的关系:在两张表中的任意一张表中建立关联字段+unique

建关联关系是为了查询,建约束关系是为了维护数据的完整.

约束关系存在的目的,删除被关联表的一条数据,如果两表只有关联字段,无约束关系,则会直接删除.如果有约束关系,则无法直接删除,会有提示,无法删除.

如上表,如果删除publish表中的第1条数据,则再查下时将无法查出php书籍的出版社信息.所以增加了约束关系,使得操作者无法随意删除.

若只有关联关系而无约束关系,就可以直接删除.

上图的publsish_id字段是两表的关联字段,上图的foreignkey就是建立约束关系

THE END
1.电脑常用浏览器有哪些?电脑浏览器大全浏览器下载安装2024最新版蚂蚁安全浏览器(MyIE) 1.53M / 2017-06-26 / v9.0.0.375 官方免费版 评分: 下载 蚂蚁浏览器是一款功能十分强大的pc电脑浏览器,能够自动为用户备份收藏,具有误删恢复,异地漫游等深受用户喜爱的功能。更有强大的皮肤支持功能,可以更换各种美观独特的皮肤。欢 http://www.downyi.com/key/liulanqi/
2.浏览器排行榜前十名百度 搜索 查询 立即下载 alook安卓版 2024-08-31 浏览器 立即下载 maxthon浏览器 2024-05-22 浏览器 立即下载 搜狗浏览器极速版 2024-07-17 浏览器 立即下载 十大相关软件专辑 网页浏览器软件 可以看网页视频的浏览器推荐模拟器软件安卓模拟器app手机模拟器软件伪原创文章生成器软件安卓模拟器连点器访https://m.pianwan.com/s/zj-1444374
3.浏览器十大品牌浏览器哪个好入选《 2024年CNPP浏览器行业十大品牌榜中榜名录》的有:CHROME、Edge浏览器、360安全浏览器、Safari、QQ浏览器、UC浏览器、火狐、360极速浏览器、搜狗高速浏览器、欧朋等,该名录是以大数据算法、人工智能、客观真实公正统计计算为基础,通过广泛收集整理汇编全球权威资料,综合多家机构媒体和网站公布的排行榜单数据,结合专https://www.cnpp.cn/china/list_7240.html
4.电脑技巧:电脑上最好用的10个浏览器排行榜很长时间都在市场份额上占很大地位。优点也多,网页加载速度非常快,界面设计简洁高效,多进程架构也很厉害,能保证浏览器不会因为恶意网页和应用软件就坏了。每个标签、窗口和插件都在自个独立的环境里运行,安全性很高。而且还有很多插件和扩展程序,能满足用户各种不一样的需求。https://blog.csdn.net/xishining/article/details/144073926
5.十大浏览器品牌手机浏览器哪个好2024年浏览器十大品牌最新发布,浏览器排行榜前十名品牌有CHROME、Edge浏览器、360安全浏览器、QQ浏览器、Safari、UC浏览器、360极速浏览器、火狐、搜狗、欧朋。浏览器10大品牌排行榜由品牌研究部门收集整理大数据分析研究得出,帮助你了解pc浏览器哪个好用。https://m.maigoo.com/maigoo/7240llq_index.html
6.ie系列浏览器有哪些导读IE系列浏览器包括以下几种:1. Internet Explorer:简称为IE浏览器,是微软公司推出的一款常用浏览器。因其强大的功能、易用性和稳定性而 IE系列浏览器包括以下几种: 1. Internet Explorer:简称为IE浏览器,是微软公司推出的一款常用浏览器。因其强大的功能、易用性和稳定性而受到许多用户的青睐。目前最新的http://news.shooba.com.cn/kjhl/202411/694815.html
7.手机网络浏览器有哪些?安卓浏览器app下载安卓浏览器哪个好?安卓手机用什么浏览器最好?2265安卓网网络浏览栏目,为您提供全网最新、最热、最好用的网络浏览器软件,供您安卓手机使用!http://2265.com/fanqiangluyouqi
8.pc浏览器有哪些好用的pc浏览器下载大全电脑浏览器应该是大家日常都会使用到的一款软件,大家可以在这些软件中搜索自己感兴趣的内容,下载各种软件资源,浏览各种信息,大家需要的任何内容都能在这些浏览器中找到,小编给大家介绍一些常用的pc浏览器软件,都支持打开无痕浏览模式进行私密阅读,提供各种语音搜索功能等,给大家带来便捷的搜索内容体验,需要的用户快来下载http://www.downcc.com/k/pcllq/
9.ie浏览器有哪些ie浏览器有哪些 导读IE浏览器即Internet Explorer,是微软公司推出的一款浏览器,历史上有很多版本。目前主流的IE浏览器版本包括:1. Internet Explorer 11 IE浏览器即Internet Explorer,是微软公司推出的一款浏览器,历史上有很多版本。目前主流的IE浏览器版本包括:http://m.jttv.org.cn/hlwdzx/202411/543915.html
10.各种浏览器图标大全熊猫办公精心为用户挑选80张高清精美浏览器图片、支持专业级浏览器设计素材下载,更多风格的浏览器,免抠元素,卡通手绘素材图片、图标图案、免抠矢量图,尽在熊猫办公。https://www.tukuppt.com/speciall/liulanqi2347.html
11.如何把电脑上的浏览器放到桌面上?windows图片浏览器9. 点击“下一步”按钮,输入快捷方式的名称; 电脑将自带浏览器图标放在桌面的方法如下 1、首先打开电脑,点击打开左下角开始图标中的“浏览器”。 2、然后在弹出来的页面中点击打开一个想要发送到桌面的网页,复制网页地址。 3、然后返回桌面,右键单击电脑桌面,选择新建一个快捷方式。 https://www.shiwaiyun.com/article/post/68045.html
12.>第2章Solaris运行时问题当针对 Solaris 高可靠扩展版配置 x64 系统时,除超级用户以外,其他具有管理角色的用户无法在控制台上连接到 X 窗口服务器。应用程序将无法启动。不会显示任何错误消息。 解决方法:允许来自本地主机的 TCP 连接。要允许 TCP 连接,请创建/etc/X0.hosts文件,并添加带有全局区域的主机名的一行。 https://docs.oracle.com/cd/E19253-01/820-1877/6ndh3vjte/index.html
13.浏览器改名称图标变成白色浏览器改名称图标变成白色 win10 edge图标变白色?win10 edge浏览器图标变成白色的处理方法 win10 edge浏览器图标变成白色的处理方法如下: 1. 鼠标右键桌面——显示设置。 2. 显示设置。 3. 滑块向左移动——调节到100%——应用。https://www.qn200.com/k/7jw6y2le2.html
14.银符考试题库在线练习B.调制解调器 C.打印机 D.浏览器 A B C D 58. 计算机网络按其覆盖的范围,可划分为 。 A.以太网和移动通信网 B.电路交换网和分组交换网 C.局域网、城域网和广域网 D.星形结构和总线结构 A B C D 59. 根据域名代码规定域名为www.yfzxmn.com表示的网站类别应是 。 A.教育机构 B.军事部门 C.http://www.cquc.net:8089/YFB12/examTab_getExam.action?su_Id=5&ex_Id=4790
15.如何在手机谷歌浏览器上下载视频当视频播放时,您会看到浏览器工具栏上出现一个下载按钮。该按钮通常位于地址栏旁边,并带有向下的箭头图标。 4. 选择下载质量 单击下载按钮后,您将看到一个选项菜单,其中包含各种下载质量。选择您想要的质量,然后单击“下载”按钮。 5. 选择下载位置 接下来,您将被要求选择下载位置。选择您希望视频保存的文件夹,然后http://www.gdedu123.com/gd/509675.html
16.如何修改网页端(Html5)浏览器标签中标题图标和名称二、如何更改浏览器标签中的名称, 1、参考如下代码示例:changeBroserTitleDemo.rar,编写前端js插件 2、参考帖子将js插件部署到系统中:HTML5端如何注册全局JS文件和Css文件插件 3、重启IIS验证 代码示例: ( function($) { var customerLogin = function() { https://developer.kingdee.com/article/423774740629564928?productLineId=1&isKnowledge=2
17.软件更新装修设计教程DIY装修1) 用户登录限制 :账号在某个机器或者浏览器登陆后,尝试用同一账号在其它机器或者浏览器登陆时,之前的登陆会下线。 2) 共享自定义模型相关优化: a) 作者头像和名字移动到信息栏,显示更加统一清晰。 b) 新增了“添加到我的素材库”的权限限制,不允许添加非本人创建的自定义模型。 https://www.shejijia.com/ketang/text-detail.html?p=5217
18.亿联会议点击图标 设置为暂停/恢复发送音频。暂停接收音频后,会场/与会者被关闭接收其他终端音频的能力(包括主会场以及同声传译通道),被暂停音频的终端接收不到音频流,如果终端没有静音不影响其它会场接收此会场的音频。注:仅支持主持人进行设置。目前对浏览器客户端/微信小程序等不支持响应。 https://helpcenter.ylyun.com/help-docs/featureguide/meeting/meetingcontrol/?lang=zh
19.浏览器网站名称前面的小图标LOGO怎么更换设置?浏览器网站名称前面的小图标LOGO怎么更换设置? 网站这个小图标在哪更换? 牛牛(官方团队) 2021-09-08 16:55:09 第一步:制作一个 favicon.ico(如果不会制作可以拍:ICO制作/ICO生成/制作/favicon生成) 第二步:通过FTP或宝塔进入网站根目录/public . 第三步:替换 favicon.ico文件 即可。http://www.yqnxt.com/21_37.html
20.RazorSQL破解版数据库管理工具RichardsonRazorSQLRazorSQL破解版是一款用于Windows,macOS,Mac OS X,Linux和Solaris的SQL查询工具,数据库浏览器,SQL编辑器和数据库管理工具。RazorSQL已经在40多个数据库上进行了测试,可以通过JDBC或ODBC连接到数据库,并且支持常见的各种数据库,RazorSQL提供易于使用的可视化工具和高级功能,允许用户进行数据库浏览,编辑,管理,管理和编程。http://www.sd173.com/soft/7634.html
21.浏览器输入域名前面的icon图标称为什么简介:浏览器输入域名前面的icon图标称为什么 1.在浏览器输入域名前面的icon图标我们称为Favicon Favicon 全称“ favorite icon ” 翻译成中文:网页图标,如下图 2.其他也会遇到一些常见,但不知道规范名称的图标名称,列举出来一些 上一页图标( Back Icon) https://developer.aliyun.com/article/916018
22.www.360doc.cn/article/48475987微软坚持使用E开头的名字,这样习惯点击“蓝色E”图标的消费者会知道如何启动新的浏览器。 2018年12月6日,微软正式宣布桌面版Edge浏览器将采用Chromium内核,并将支持所有受支持的Windows版本及macos和Linux平台。 2020年1月15日,微软正式推出内核更改为Chromium的新版Edge,抛弃以往的EdgeHTML。对标志也进行修改,从原本https://www.360doc.cn/article/48475987_1046475345.html
23.UnrealEngine4游戏开发指南第1章是本书的基础。该章介绍如何和在哪里下载Unreal Engine,了解源代码版本和启动器版本之间的区别。Unreal Engine安装(如果是源代码版本,则是编译)之后,展示Unreal Engine的用户界面。该章还讲述浏览器、BSP以及如何更改游戏的启动画面和图标。 第2章讲述在启动并运行Unreal Engine后如何将自定义的FBX资源导入Unrealhttps://www.epubit.com/bookDetails?id=UB6c8733ad1529e