Django框架:路由层
Django
一、可视化界面之增删改查
针对数据对象主键字段的互殴去可以使用更加方便的obj.pk,就不用看主键字段的字段名了
补充:
a标签中
href="#"
表示不跳转form表单中能够触发提交动作的按钮只有两个
input
type="submit"
button
type="submit"
在web页面展示上和功能上一致
1.数据展示
- 开设接口、获取数据、传递页面、展示页面
(1)开设接口
在urls中添加好对应关系
前端:先编写最简单的用户数据展示页面
(2)获取数据
后端:获取数据库数据
(3)传递页面
通过模版语法展示出数据库获取的数据
2.数据的添加功能
(1)开设接口
在urls中添加好对应关系,前端:在展示数据的页面上添加新增数据的按钮,点击跳转到新增数据的页面
(2)获取数据
后端:获取前端提交的数据,添加逻辑判断后存入数据库
3.数据的编辑功能
(1)开设接口
(2)获取向编辑的用户的信息,通过get请求后添加额外的参数,将当前想修改的用户的主键传递过去,?携带参数
(3)后端获取用户数据
(4)前端展示默认数据
(5)同上
4.数据的删除功能
(1)开设接口
在urls中添加好对应关系,前端:在展示数据的页面上点击删除的按钮,执行删除的功能函数
(2)获取删除的用户id
通过request.get()
获取标签提交的数据
(3)后端判断
添加点击事件,当删除时,先判断是否真的删除,点击确定再删除
<script>
$('.c1').click(function () {
let res = confirm('确认删除用户{{ data.name }}的数据吗')
if (res) {
} else {
return false
}
})
</script>
二、Django请求生命周期流程图
1.web服务网关接口
拆包打包,将http数据打包成大字典,将后端多数据转换成http数据
web服务网关接口协议-WSGI协议,wsgiref和uwsgi都是该协议的两种不同功能模块
-
Wsgiref.py
django默认的网关接口,能承受的并发量特别低,只用于本地,实际项目中会切换成uwsgi。
解析请求格式,打包成request大字典;或者打包好数据返回给浏览器,满足HTTP协议
-
uwsgi
上线之后切换成uwsgi,并发量比wsgiref高很多
2.整个Django后端
1)中间件:Django的保安,忽略
2)路由层:urls.py -路由和视图函数的对应关系
3)视图层:views.py(每个应用有一个,多个应用总共有多个)
4)与视图层交互的模版层和模型层
-
模版层:templates目录,django提供的模版语法
-
模型层:models.py 提供orm语法,可以连接数据库
3.MySQL数据库:与模型层交互
三、Django路由层
路由和视图函数的对应关系
1.路由匹配
(1)Django的版本与路由匹配问题
django2.x以及以上,urls.py中path第一个参数写什么就匹配什么
django1.x第一个参数是正则表达式
/user_list
/user_list/
上面的两个路由是不同的,无论什么版本,django都自带自动加/
并重定向的功能,可以看到当user_list在路由匹配中找不到的时候,django会自动添加/
并重定向
该重定向功能可以取消,在settings.py中,将APPEND_SLASH改为False
(2)路由匹配本质
特点:path第一个参数写什么就匹配什么
2.转换器的有名分组
网站上都会有很多相似的网址,如果每个都单独开设路由并不合理;
所以,很多相似的路由应该整合到一起,这就用到了Django提供的转换器
(1)转换器
-
类型:字符串转换器
<str:info>
,整形转换器<int:info>
-
转换器的作用:接收多个路由拼接在一起,将对应位置匹配到的数据转换成固定类型
转换器捕捉info的时候,会将info转换成固定类型,然后当成参数传入视图函数,形式如下
index_func(request,info='类型转换后的内容')
path('路由/<str:info>/',veiws.视图函数func)
视图函数func(request, info='类型转换后的内容')
动态匹配动态内容,还可以给视图函数的穿参数进去,或者写成(request,**kwargs)
兼容性更强
视图函数func(request, **kwargs)
还支持自定义转换器,自己写正则表达式,匹配更加细化的内容
3.正则匹配re_path
re_path
简介:django 2.x及以上版本中的模块,第一个参数是正则表达式
re_path('test', views.test)
# test则是正则表达式,在输入的网址的路由中,只有含义test则立即执行对应的视图函数
正则匹配的原则:只要第一个正则表达式能够从用户输入到路由中匹配到数据就算匹配成功,就会立刻从停止在路由层匹配,而直接执行对应的视图函数
通过正则表达式的符号可以提供更多的限制
re_path('^test/$', views.test)
# 限制开头和结尾,精准匹配/test/
4.正则匹配的无名分组与有名分组
通过正则匹配,我们可以自己定义匹配的规则
(1)不分组
re_path('^test/.*?/\d+/', views.test)
对于视图函数不会传参数
test(request)
(2)无名分组
无名分组:会将括号内正则匹配到的内容当作位置参数传给视图函数
re_path('^test/(\d{4})/(.*?)/', views.test)
对于视图函数会通过位置传参的方式传递参数
test(request,\d{4}匹配到的内容, .*?匹配到的内容)
(3)有名分组
有名分组:给分组起别名(?p<别名>)
,视图函数会按照关键字传参的方式,这种叫做有名分组
有名分组:会将括号内正则匹配到的内容当作关键字参数传递给视图函数
re_path('^test/(?P<year>\d{4})/(?P<id>.*?)/', views.test)
对于视图函数会通过关键字传参的方式传递参数
test(request, year='',id='')
注意:
正则匹配的无名分组和有名分组,使用时只能选择一种,不能混合使用
四、反向解析
类似于静态文件的动态解析
通过反向解析的语法,找到对应关系
1.反向解析的含义
通过起一个别名,可以反向解析出一个结果,这个结果可以访问到一个对应到路由,可以访问到对应的一个视图函数(减少耦合,动态匹配)
2.反向解析的用法
当路由是固定的情况下
(1)路由匹配关系起别名:url匹配模式
给路由和视图函数的对应关系,起一个别名,只要别名不变,就可以通过这个别名找到他们的对应关系
(2)使用反向解析语法
在前端html页面或者后端视图函数中,使用反向解析动态匹配路由
3.动态路由的反向解析
(1)正则匹配的反向解析
1) html页面上的模版语法
{% url '对应关系别名' %}
2)后端语法
通过导入reverse模块,填写路由和视图函数对应关系的别名,可以反向解析出他们的对应关系
reverse('login_view')
- 例
# urls.py中
re_path('index/(?P<year>\d+)/', views.infex, name='index_view')
# html页面上
# 1.可以直接写出限制的数据
<a href='/index/1/'></a>
<a href='/index/123/'></a>
# 2.也通过模版语法
{% url %}
<a href='{% url "index_view" "321" %}'></a>
# 对应
/index/321/
# 后端views.py中,通过reverse中的参数args来增加限制
url = reverse('index_view', args=('111',))
/index/111/
(2)转换器的反向解析-
1.前端上
- 路由中有动态的部分-->转换器
- html页面上使用模版语法
除了在视图函数中传一个关键字参数,需要在html页面上,将路由中动态的部分做一个限定
2.后端语法
通过reverse中args参数传递动态解析的限制
- 例
# urls.py中
path('index/<str:info>', views.index, name='index_view')
# html页面上
# 1.可以直接写出限制的数据
<a href='index/jason/'></a>
<a href='index/kevin/'></a>
# 2.也通过模版语法
{% url %}
<a href='{% url "index_view" info="jason" %}'></a>
# 对应
/index/jason/
# 后端views.py中,通过reverse中的参数args来增加限制
url = reverse('index_view', args=('tony',))
/index/tony/
五、路由分发
基于Django开发应用,Django支持每个应用都可以有自己独立的路由层urls.py文件、静态文件static文件夹、模版层templates文件夹。
当一个django项目中的url特别多的时候,总路由:Django同名目录下的urls.py中的代码会很复杂、冗余,耦合度很高,这个时候可以通过路由分发的方法,减轻总路由的压力
多人开发的优点:在多人共同开发一个项目时,就可以减少耦合,之后通过路由分发可以整合到一起
按照应用将路由拆分
1.路由分发简介
路由分发:在每个应用目录下建立自己的子路由urls.py
文件,然后在总路由中添加每个app的urls.py
的路径,由总路由做路由分发的处理。当请求数据经过路由层的时候,就会识别当前url
属于哪个app,直接发给对应的app,在通过app下的子路由去处理
2.路由分发的实现
-
子路由
在应用目录下建立
urls.py
文件
# 在子路由中
from django.urls import path
from app01 import views
urlpatterns = [
path('index/', views.index_func),
]
-
总路由
总路由中导入include,将子路由的关系导入,通过
path('app名/', include('app名.urls'))
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('app01/', include('app01.urls')),
]
2.名称空间
当我们在Django项目中建立了多个应用,并在路由对应关系中出现了相同的别名的时候,正常情况下的反向解析是无法自动识别前缀的
如果想找正常识别区分有两种方式
(1)方式一:名称空间
有亿点点麻烦
- 总路由
-
html页面
通过模版语法,但是要加应用目录
-
后端
使用reverse反向解析的时候加应用前缀
url = reverse('app01:view_index')
print(url)
# /app01/index/
(2)方式二:其别名的时候加前缀
推荐使用
多个应用子路由中,给路由和视图函数的对应关系起名的时候,可以用作用名作为别名的前缀,防止别名重复导致的冲突
- 子路由
- 总路由
- html页面上
- 后端
url = reverse('app02_view_index')
print(url)
# /app02/index/
六、虚拟环境
- 场景:不同的项目需要不同的模块
虚拟环境:相同版本的解释器,创建多个分身,每个分身可以有自己独立的环境
python的虚拟环境类似于虚拟机,能够创建一个独立的python运行环境,
虚拟环境中的安装的第三方依赖包和全局环境中的包相互独立,不会影响全局的python环境
1.pycharm创建虚拟环境
每创建一个虚拟环境,就相当于重新下载了一个全新的解释器
- 新建python解释器的虚拟环境
- 终端中已经切换到虚拟环境
2.命令行
在python3.3之前的版本要下一个venv
模块,3.3之后的版本都自带venv
模块
- 创建python 的虚拟环境
python -m venv 存放虚拟环境python的目录名
这时的命令不支持多版本选择,在环境变量中,哪个python版本在最上端,就是以哪个为准创建环境变量
默认新建的虚拟环境中没有全局环境中的第三方依赖包,若需要访问全局环境中的包可添加参数
- 切换到虚拟环境的bin目录下,激活虚拟环境
cd 目录名/bin
source activate
- 进入虚拟环境中
(目录名) % 表示激活虚拟环境成功
- 退出虚拟环境
deactivate