django day 03
今日内容详细
- 作业讲解之数据展示
- 作业讲解之数据添加
- 作业讲解之数据编辑
- 作业讲解之数据删除
一、作业
------查询所有数据的偏门方法----filter
这里filter是过滤的意思,如果括号内什么都不写,就相当于过滤条件为空等价于 select * from 一张表

-----解释:
就是将data_queryset所对应的数据传递给userlist.html这个页面,并且在userlist.html这个页面,通过以单引号内的data_queryset这个键就能拿到这个数据

----这里的href指代了它到底往哪个地址上跳---

-----去查询获取到的这个用户名是否已存在-----

前端给后端传递信息有两种方式:
① form表单的提交
② GET携带
我们可以在编辑的按钮后面以问号形式将每个数据的id值写进来,这样每个数据的id都会在url里面携带进去

-----在编辑数据页面上能显示出当前编辑的默认数据------

-----出现下面这个样子----

-----涉及到url后缀的,一定要/开头/结尾

二、django请求生命周期流程图
1、django的中间件相当于保安,保证框架的安全性
2、如果是全栈项目,会用到html页面----->模板层(存放在templates文件夹中)
3、模板里可能用到模板语法, 然后去数据库拿到数据(模型层),然后用orm到数据库中操作,然后orm 帮你封装成数据对象,然后在视图层里做数据的渲染
4、然后把html页面渲染好了之后,那么他会直接由视图层到中间件,由这个保安再做一次数据校验,怕你携带危险数据出去了,发现你没有问题,然后保安会把这个数据交给服务网关接口,让他去打包,打包好了之后才会交给浏览器

ps:(1) wsgiref 和 uwsgi 是实现WSGI协议的模块
(2) django的中间件类似django的保安,他来负责django框架的安全性

1.用户输入网址,浏览器发起请求
2.WSGI(服务器网关接口) 创建socket服务端。接受请求
3.中间件处理请求
4.url路由,根据当前请求的url找到相应的视图函数
5.进入view,进行业务处理,执行类或者函数,返回字符串
6.再次通过中间件处理响应
7.WSGI返回响应
8.在视图层通过模板语法进行浏览器渲染


三、路由匹配
django2.X 以上路由匹配用的方法是path
1.路由匹配 path
path('网址后缀',视图函数名/类名)
一旦网址后缀匹配上了就会自动执行后面的函数
并结束整个路由的匹配
(1)路由结尾的斜杠
①默认情况下不写斜杠,django会做二次处理:第一次匹配不上,会让浏览器加斜杠再次请求
②django配置文件(settings)中可以指定是否自动添加斜杠(有这个方法,但没必要使用)
APPEND_SLASH = False

(2)path转换器匹配(仅在django2以上才有)
使用场景:将来,你的路由里面需要接收一些不确定的因素的时候,可以使用转换器来匹配
<int:year> 这个参数只能传数字
path('func/<int:year>/',views.func)
由于func这个前缀已经写死了,所以前缀一定有一个func,由于<int:year>没有被写死,所以后缀可以是任何数字,如果写了数字以外的东西也不会导致后端报错,只会在前端显示404提示信息。
五种转化器:
✡ 'int': IntConverter() 捕获到的数据都会转成整型
'path': PathConverter()
'slug': SlugConverter()
✡ 'str': StringConverter() 捕获到的数据都会转成字符型
'uuid': UUIDConverter()
path('func/<int:year>/<str:info>/',views.func)
转换器匹配到的内容会当做视图函数的关键字参数传入 :比如说上面这句话就意味着func这个函数除了request这个参数,还要加上year和info这两个参数(如下)
def func(request,year,info):
pass
转换器匹配到的内容会当做视图函数的关键字参数传入
转换器有几个叫什么名字,那么视图函数的形参必须对应
-------只能在前端传数字---------

❗ 2.re_path正则匹配
re_path(正则表达式,函数名)
一旦网址后缀的正则能够匹配到内容就会自动执行后面的函数,并结束整个路由的匹配
re_path('^test/$',views.test)
当网址后缀不固定的时候,可以使用转换器来匹配
----这里是用re_path里面的正则去匹配网址中输入的后缀,只要匹配到后缀中的文本,就算匹配上

-----这里是首先我们拿着正则test/去匹配,因为敲入的后缀中testadd中的test后面没有斜杠,那么这一次就匹配失败了,去匹配第二个路由,同样因为后缀testadd后面没有斜杠,所以也失败了,然后django自动给你敲入中的后缀加上斜杠,再去匹配,这次在第二个路由中匹配成功了。

------正则匹配,只要有符合的正则就能匹配得上-----

------但是上面这种就感觉不太规范,于是就有了下面这种进化模式----

------这样你只能敲test或者test/,哪怕稍微在后面加一点点东西都会404

3.正则匹配之无名分组
/ 是数字 +是一个或多个
① re_path('^test/(\d+)/'),views.test 只有两个后缀
-----在后缀的后面加数字会报错

-----报错原因找到了,我们要将(/d+)作为位置参数传给函数,所以函数的参数应该是有两个的----

def test(request,XX):
print(XX)
② re_path('^test/(\d+)/(.*?)) 有三个后缀,且第三个后缀可以写成是任何东西
这里面的(.*?)就是贪婪匹配,代表第三个后缀可以写任何东西,但一定要记得在函数里面再多加一个位置参数
正则表达式匹配到的内容会当做视图函数的位置参数传递给视图函数 位置参数就是函数的第二个参数不必要和正则的名字相对应,可以随便起名,也就是没有名字
4.正则匹配之有名分组
re_path('^test/(?P<year>\d+)/(?P<others>.*?)/',views.test)
注意了:?P<year>和?P<others>只是个别名,\d+和.*?才是正则 ; 同时这一行代码和转换器path是一样的了,需要传入关键字参数才行
正则表达式匹配到的内容(year和others)会当做视图函数的关键字参数传递给视图函数
5.django版本区别 【面试的时候小装一波】
在django1.11中,只支持正则匹配,并且方法是 url( )
django2,3,4中,没有url了,只有path() re_path(),re_path()等价于django1版本中的 url()
ps怎么装:可以主动说出来django这一块是有区别的,从而体现出你这家伙知识面比较广嘛
四、反向解析 (路由的反向解析)
反向解析的话就是什么版本都是一样的
ps:方向解析的目的是防止,我们写好了路由之后,路由被改了,整个页面都跟着改
问题:页面上提前写死了很多路由,一旦路由发送变化会导致所有页面相关链接失效
为了防止出现该问题,我们需要使用反向解析
反向解析:返回一个结果,该结果可以访问到对应的路由
1.路由对应关系起别名
path('register/', views.reg, name='reg_view')
第三个参数 name='reg_view'相当于是给前两面的这一组对应关系起了一个名字
总结:无论路由名字怎么变,将来都能通过别名找到这个路由,根据路由关系对应的别名,就会给你一个结果,你拿这个结果就能访问到路由;这个就叫反向解析
2.使用反向解释语法
①html页面上的反向解析
{% url 'reg_view' %}

②后端的反向解析(三板斧中还有一个reverse,reverse是专门用来做反向解析的)
from django.shortcuts import reverse
reverse('reg_view') # reverse后面写一个上面的别名就可以
ps:反向解析的操作三个方法都一样path() re_path() url()
五、无名有名反向解析
1.引入反向解析
当路由中有不确定的匹配因素,反向解析的时候需要人为给出一个具体的值
后端:
reverse('reg_view', args=('jason',)) # 有几个不确定因素,就加几个在后面
前端:
{% url 'reg_view' 'jason' %} # 有几个不确定因素,就加几个在后面
ps:反向解析的操作三个方法都一样path( ) re_path( ) url( )
总结:反向解析的目的就是你要有一个结果,这个结果要匹配上对应的路由

六、路由分发
1.django中的应用都可以有自己独立的
urls.py templates文件夹 static文件夹
能够让基于django开发的多个应用完全独立,便于小组开发
2.总路由(规划一下子路由)
path('app01/',include('app01.urls')),
path('app02/',include('app02.urls')),

3.子路由
path('after/',views.after) # app01
path('after/',views.after) # app02
当项目特别大,应用特别多的时候,可以使用路由分发,非常方便!!!
ps:如果两个app的应用的路由相同,就需要给各自的路由起别名,如下:


但是这样有些麻烦,那么django提供了一下方法,能够让我们更方便的匹配路由:

七、名称空间
有路由分发场景下多个应用,在涉及到反向解析别名冲突的时候,无法正常解析
解决方式一:很复杂
名称空间
namespace
path('app01/', include(('app01.urls', 'app01'), namespace='app01'))
path('app01/', include(('app01.urls', 'app02'), namespace='app02'))
后面的namespace意思是,不单单要给路由做一个分发,还要给各自创建一个单独的名称空间

解决方式二:
别名不冲突即可
“”保证django项目下没有重复的别名即可“”
那么如何保证别名不冲突呢,就是在别名的前面加上应用名的前缀,这样就一定不会重名了

浙公网安备 33010602011771号