• Django之路由层


    目录

    django请求生命周期流程图

    路由匹配

    分组命名匹配

    无名分组

    有名分组

    传递额外的参数给视图函数

    命名URL 和 URL反向解析

    命名URL

    URL反向解析--前端

    URL反向解析---后端

    无名分组反向解析

    有名分组反向解析

    路由分发

    名称空间


    django请求生命周期流程图

    django的生命周期是:前端请求--->nginx--->uwsgi.--->中间件--->url路由---->view视图--->orm---->拿到数据返回给view---->试图将数据渲染到模版中拿到字符串---->中间件--->uwsgi---->nginx---->前端渲染。

    django请求声明周期流程图
     浏览器基于http协议发送请求>>>进入django的web服务网关接口(wsgiref, tashidjango默认的网关接口,但是并发量很低,所以上线后都会切换为uwsgi以提高并发量, [wsgi是一个协议, 剩下两个都是基于此协议的模块]), 当请求来的时候拆解数据,相应走的时候封装数据, >>>进到django后端[整个django框架]
    先经过django中间件,类似于安保系统, 经过筛选后才会将数据传到后边,>>>>进入urls.py 路由层. 在路由曾栗晚成路径匹配, 有了确定路径之后进入视图层,>>>views.py 视图层执行核心业务逻辑,若是全栈项目就需要用到HTML页面,若只写后端接口则不用HTML, >>>>templates文件夹,模板层, >>>>模型层 models.py 去跟数据库做交涉, 模型层链接数据库MySQL.    视图层需要模板的话去模板层拿模板,需要数据的话去模型层拿数据, 根据orm去MySQL里操作, MySQL返回数据,orm将它封装成数据对象,在视图层通过模板语法做一个模板语法渲染, 渲染完之后,直接由视图层返回到中间件,再次经过校验,然后中间件将数据交给网关接口去打包,打包完成之后发送给浏览器,  >>>浏览器接收数据. 

    其实在wsgiref之前还有一个nginx,做一个反向代理,提升其并发量,  在整个流程外还有一个缓存数据库,想要请求数据时, 会先去缓存数据库里找, 没有找到的情况下才会去MySQL找. 


    学习先从 路由层开始, >>>视图层>>>模板层>>模型层>>>django插件>>>django中间件
     

    中间件的作用非常大,可以处理所有的请求内容,中间件其实就是一个类,这个类中一共有5个方法,

    分别是

    process_request,

    process_response,

    process_view,

    process_exception,

    process_render_template,

    下面说一下它的运算顺序

    当一个请求,首先从上往下运行这些类中process_request方法,之后进入django的从上往下执行每个类中的process_view方法,在然后就进入我们自定义的view.py文件,如果你的试图中有错误,那就会从下往上执行中间件中的process_exception方法,然后把错误信息在通过process_response中返回给客户端。

    process_request:在这个方法中是没有return方法的,如果有那就会执行process_response方法,直接返回给客户端,一般情况下我们是不会在这里返回内容的,除非你有需求,判断发过来的请求过来的内容,如果不是很友好的请求,那么我们直接就可以在这返回,直接卡死,让这个请求直接都进不了我们的django中的内部程序,

    process_response:在这个方法中我们必须要有return方法,这样才能一步一步的返回给客户端,当然你也可以写一些东西在response里,在这里写就是会在所有的response里都会有你所添加的内容!

    process_view:这个方法中是没有return方法的,如果有那就走process_response方法;

    process_exception:在这个方法中是一定要有return方法的,这个方法是专门返回你的错误信息的,我可以在所有的视图函数只要出现错误就会执行这个方法,可以返回一个错误模版信息!

    路由匹配

    urls.py

    1. from django.conf.urls import url
    2. urlpatterns = [
    3. url(正则表达式, views视图函数,参数,别名)
    4. ]

     参数说明

    • 正则表达式:应该正则表达式字符串
    • views视图函数: 一个可调用对象, 通常为一个视图函数或一个指定视图函数路径的字符串
    • 参数: 可选的要传递给视图函数的默认参数(字典形式)
    • 别名:一个可选择的name参数

    注意事项

    1. urlpatterns中的元素按照书写顺序从上往下逐一匹配,一旦匹配成功则不再继续

    2. 若要从URL中捕获一个值, 只需要在他周围放置一对括号(分组匹配)

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

    4.每个正则表达式前面的r是可选的, 但是建议加上.

    是否开启URL访问地址后面不为/跳转至带有/的路径配置项 APPEND_SLASH = True

     django settings.py配置文件中默认没有APPEND_SALSH这个参数. 但是django默认这个参数为APPEND_SALSH=True. 其作用就是自动在网址结尾加/.

    访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/ 

    如果在settings.py中设置了 APPEND_SLASH=False,此时我们再请求 http://www.example.com/blog 时就会提示找不到页面

    分组命名匹配

    无名分组

    1. urlpatterns = [
    2. url(正则表达式, views视图函数,参数,别名)
    3. ]

    由于第一个参数是正则表达式, 那么就可以给正则的条件加上(),进行分组

    1. urlpatterns = [
    2. url(r'^test/(\d+)/',views.test)
    3. ]

     然后就会报错:test() takes 1 positional argument but 2 were given
    说我们给了两个参数

     views.py

    1. def test(request,a):
    2. print(a)
    3. return HttpResponse('你好啊,大漂亮')

    再启动

     无名分组>>>>路由匹配时,如果对正则表达式进行分组,那么会传入除了request参数外,还会分组后匹配到的内容

    有名分组

    有名分组其实就是对正则表达式分组之后,对分组的内容起了个别名, 同时传入视图函数的时候, 需要特定这个别名的关键字参数来接收

    1. urlpatterns = [
    2. url(r'^test/(?P\d+)/',views.test)
    3. ]

    形参中必须要有正则表达式分组起了别名的关键字参数

    1. def test(request, user_id):
    2. return HttpResponse(f'test url,{user_id}')

    无名分组和有名分组不能还在同一个url中混用, 但是可以某种类型重复使用

    传递额外的参数给视图函数

    URLconfs 具有一个钩子,让你传递一个python字典作为额外的参数传递给视图函数.

    django.conf.urls.url() 函数可以接收一个可选的第三个参数,他是一个字典, 表示想要传递给视图函数的额外关键字参数

    1. from django.conf.urls import url
    2. from . import views
    3. urlpatterns = [
    4. url(r'^blog/(?P[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
    5. ]

    在这个例子中, ,对于/blog/2005/请求,Django 将调用views.year_archive(request, year='2005', foo='bar')

    命名URL 和 URL反向解析

    命名URL

    通过name属性来命名, 注意: 多个URL命名是不可重复的

    1. urlpatterns = [
    2. url(r'^home/', views.home, name= 'home'),
    3. ]

    那么给URL命名的场景是什么?

    URL反向解析--前端

    在urls.py中给某个路径的后缀起了别名之后, 在模板HTML文件中,就可以直接根据{% url'别名''%}直接拿到别名的路径, 而不是手动拼接路径. 这样做的好处在于. 入股哦有修改ur的时候, 就不需要手动到模板文件中一个个修改了

    1. urlpatterns = [
    2. url(r'^home/', views.home, name= 'home_view'),
    3. url(r'^index/', views.index, name= 'index_view'),
    4. ]

    views.py

    1. from django.shortcuts import render, HttpResponse, redirect
    2. def home(request):
    3. return render(request, 'home.html')
    4. def index(request):
    5. return HttpResponse('from index')

    home.html

    1. "en">
    2. "UTF-8">
    3. Title

    此时修改urls.py

    1. urlpatterns = [
    2. url(r'^home/', views.home, name= 'home_view'),
    3. url(r'^index666/', views.index, name= 'index_view'),
    4. ]

    会发现反向解析的链接,能够自动解析新的路径!!

    URL反向解析---后端

    方式一:reverse模块

    views.py文件

    1. # 模块导入
    2. from django.shortcuts import redirect, reverse
    3. def func(request):
    4. _url = reverse('index_view')
    5. return redirect(f'{_url}')

    urls.py

    1. urlpatterns = [
    2. url(r'^home/', views.home, name= 'home_view'),
    3. url(r'^index/', views.index, name= 'index_view'),
    4. url(r'^func/', views.func, name= 'func_view'),
    5. ]

    结果:

    “GET /func/ HTTP/1.1” 302 0
    “GET /index/ HTTP/1.1” 200 10

    方式二:

    views.py文件

    1. # 模块导入
    2. from django.shortcuts import redirect
    3. def func(request):
    4. # 可以直接写别名,也会自动跳转
    5. return redirect('index_view')

    “GET /func/ HTTP/1.1” 302 0
    “GET /index/ HTTP/1.1” 200 10

    无名分组反向解析

    1. urlpatterns = [
    2. url(r'^test/(\d+)/',views.test,name='test_view'),
    3. ]
    1. def test(request, a):
    2. res = reverse('index_view')
    3. print(res)
    4. return HttpResponse('from test')

    当url中对正则表达式进行分组之后,视图函数反向解析出/test/之后,需要继续做后缀的匹配,如果不给一个确切的值的话,那么/test/1/、/test/2/、/test/666/都符合匹配规则,所以视图函数还需要一个参数来匹配/test/之后的参数
    后端语法:

    1. def test(request,a):
    2. res = reverse('index_view', args=(666,))
    3. print(res)
    4. return HttpResponse('from test')

    结果展示为:/test/666/

    如果无名分组有多个,那么在args括号内一次传入多个即可
    前端模板语法:{% url ‘index_view’ 666 %}

    有名分组反向解析

    1. urlpatterns = [
    2. url(r'^test/(?P\d+)/',views.test,name='test_view'),
    3. ]

    后端语法:

    1. def test(request, user_id):
    2. res = reverse('index_view', kwargs={'user_id':666, })
    3. print(res)
    4. return HttpResponse('from test')

    前端模板语法: {% url 'index_view' user_id=666 %}

    路由分发

    当一个项目的应用非常多时,在urls.py文件中urlpatterns列表中的路由会非常多,这样会导致非常不好管理路由,这时考虑将一个urls.py文件拆分开,每一个应用单独新建一个urls,py,通过总的路由文件对每个应用的路由文件进行统筹管理

    子路由中的路由配置还是按照之前的方式,但是总路由的配置需要改变

    导入模块include
     

    1. from django.conf.urls import include, url
    2. urlpatterns = [
    3. url(r'^admin/', admin.site.urls),
    4. url(r'^app01/', include('app01.urls')), # 可以包含其他的URLconfs文件
    5. url(r'^app02/', include('app02.urls')), # 可以包含其他的URLconfs文件
    6. ]

    路由匹配时,如果匹配到/app01/会直接到app01.urls.py文件中去继续做路由匹配

    名称空间

    Django 项目中有两个应用–app01与app02,分别有其各自的urls.py

    如果两个项目都有一个url(r’^index/',views.index,name=‘index_view’), 即多个应用出现路由命名冲突的情况!

    此时,对index_view这个别名进行反向解析时,能够解析出是属于app01的,还是app02的呢?

    直接说结论:当一个项目中有相同的路由命名,只会识别到最后一个起了这个名字的路由,其他的相同命名的路由,无法被反向解析出来

    解决办法:在总路由进行路由分发的时候,给每个应用进行命名空间namesapce=的起别名操作
    创建多个应用 并去配置文件中注册

    1. INSTALLED_APPS = [
    2. ‘app01’,
    3. ‘app02’
    4. ]

    总路由:

    1. from django.conf.urls import include, url
    2. urlpatterns = [
    3. url(r'^admin/', admin.site.urls),
    4. url(r'^app01/', include('app01.urls',namespace='app01')),
    5. url(r'^app02/', include('app02.urls',namespace='app02')),
    6. ]

    各自的app的urls.py

    1. urlpatterns = [
    2. url(r'^index/',view.index,name='index_view')
    3. ]

    这样在各自的视图函数进行反向解析的时候会有不同的提示

     其实,该问题的解决方法还可以在给路由重命名时,加上应用的前缀app01_index_view这样可以不使用名称空间,同样达到相同的效果

  • 相关阅读:
    PokéLLMon 源码解析(一)
    ShardingSphere入门
    互联网摸鱼日报(2022-12-06)
    win11 电脑 使用 python 连接USB 海康工业相机 运行示例程序 BasicDemo.py 并添加连续捕捉图像(可以自己合成视频)的两个按钮
    异常检测 | MATLAB实现BiLSTM(双向长短期记忆神经网络)数据异常检测
    Dockerfile
    java 实现深拷贝list 、map
    从一个 issue 出发,带你玩图数据库 NebulaGraph 内核开发
    整型变量的原子操作
    web前端期末大作业 html+css+javascript汽车销售网站 学生网页设计实例 企业网站制作
  • 原文地址:https://blog.csdn.net/weixin_67531112/article/details/126647346