路由层

内容概要

  • django请求生命周期图
  • django路由层
  • 反向解析
  • 路由分发
  • 名称空间
  • 虚拟环境

django请求生命流程图

客户端会发送的请求会先到web服务网关接口然后到django后端先到中间件,中间件相当于保安,先过滤一遍如果不合法会你从哪里来回哪里去,然后到路由层,如果匹配上了回到视图层做操作,如果需要页面则去模板层要数据如果需要数据库的数据则去模型层要数据,模型层会去数据库要数据然后用模板语法进行操作然后返回给中间件中间件在过滤一边然后给web服务网关接口在返回给客户端

django路由层

  1. 路由匹配

    django2.X及以上 path第一个参数写什么就匹配什么

    django1.X版本第一个参数是正则表达式

    无论什么版本django都是自带加斜杠后缀的功能 也可以取消配置文件中的 APPEND_SLASH = False

    我不加/django会自动给我加,这是django的功能,当你发的不加/的时候匹配了一遍,没有匹配成功,会让你加个/在来匹配一遍如果还没匹配成功则报错

    如果不要这个功能则在settings.py里添加这行代码 APPEND_SLASH = False

    它就不会自动添加/

转换器

正常情况下很多网站会有很多相似的网址 如果我们每一个都单独开设路由不合理

django2.X及以上版本由动态匹配由转换器(五种)

str:匹配除路径分隔符外的任何一个非空字符串

int:匹配0或者任意正整数。

slug:匹配任意一个由字母或数字组成的字符串

uuid:匹配格式化后的UUID

path:能够匹配完整的URL路径

ps:还支持自定义转换器(自己写正则表达式匹配更加细化的内容)

http://www.cppcns.com/jiaoben/python/392724.html

转换器 将对应位置匹配到的数据转换成固定的类型

    #转换器 将对应位置匹配到的数据转换成固定的数据类型
    path('index/<str:info>', views.index_func),
    # index_func(实参request对象,info='转换器匹配到的数据转换后的内容')

就直接报错了,说没有一个路由跟index对应,这时候我们刚定义的那个info就得需要写东西了

我写了东西 还是报错,说index_func()函数获得一个info的关键参数,说白了就是index_func()需要一个info形参来接收。

这样就可以了

可以以传一个也可以传多个

path('index/<str:info>/<int:id>/', views.index_func)
 # index_func(实参request对象,info='转换器匹配到的数据转换后的内容', id='转换器匹配到的数据转换后的内容')

  • 正则匹配

    django2.X及以上版本有re_path 第一参数是正则

    匹配的本质是只要第一个正则表达式能够从用于输入的路由中匹配到数据就算匹配成功,匹配成功会立刻停止路由层其他匹配直接执行对应的视图函数

    re_path('text/', views.index_func)
    

这样写只要你路由有text那么就算匹配成功

django1.X版本路由匹配使用的是url() 功能与django2.X及以上的re_path()一致

  • 正则匹配的无名有名分组

    无名分组

    re_path('text/(\d{4})/', views.index_func)
    # 会把()里的匹配到的路由当成位置参数 传给后面的视图函数
    

    index_func()需要一个位置参数但是给传了两个

  • 有名分组

        re_path('text/(?P<info>\d{4})', views.index_func)
        # ?P<起的名字> 它会把匹配到的数据 以关键字的传给视图函数
    

    说的是 视图函数缺少一个形参info

反向解析

通过一个名字可以反向解析出一个结果 该结果可以访问到某个对应的路由

基本使用

  1. 路由匹配关系起别名

    path('login/', views.login_func,)
    

    可以看到我现在的所有 a标签跳转的路径都是login,我现在又login这路由,但是我如果改一下login这个路由是不是,我这个标签的路由都得改,太麻烦了,有没有一种可以动态匹配的方式。

    有可以给这个路由的起一个名字

    path('loginsdad/', views.login_func, name='login')
    
    <a href="{% url 'login' %}">嘿嘿</a>
    模板语法
    

    这样就可以动态匹配了

  2. 动态路由反向解析

    path('login/<str:info>/', views.login_func, name='login')
    
    <a href="{% url 'login' 'jason'%}">嘿嘿</a>
    <a href="{% url 'login' 'dsada'%}">嘿嘿</a>
    <a href="{% url 'login' 'wdd'%}">嘿嘿</a>
    <a href="{% url 'login' 'sdadas'%}">嘿嘿</a>
    <a href="{% url 'login'  'dsadada'%}">嘿嘿</a>
    

     path('login/<str:info>/<int:id>/', views.login_func, name='login')
    

    需要几个参数就必须传几个参数

路由分发

django支持每个应用都可以有自己独立的路由层、静态文件、模板层。基于该特性多人开发项目就可以完全解耦合,之后利用路由分发还以整合到一起

多个应用都有很多路由与视图函数的对应关系 这个时候可以拆分到各自的路由层中

    path('app01/', include('app01.urls')),
    path('app02/', include('app02.urls')),

先在主路由匹配,看到有app01的前缀后直接跳到app01.urls里面去进行下面的匹配,如果匹配不到则报错

名称空间

路由分发之后 针对相同别名能否自动反向解析出不同的应用前缀

默认情况下无法直接识别应用前缀

如果想要实现正常识别区分有两种情况

会出现那个在最后识别的都是那个

方式1:名称空间

​ 总路由

    path('app01/', include(('app01.urls', 'app01'), namespace='app01')),
    path('app02/', include(('app02.urls', 'app02'), namespace='app02')),

在app01中的视图函数
    	反向解析
        reverse('app01:index_view')
在app02中的视图函数
		反向解析  需要在前面加前缀
        reverse('app02:index_view')

方式2:别名不冲突即可

​ 多个应用别名不冲突可以应用名作为别名的前缀

在app01的urls里
	path('index/', views.index_func, name='app01_wuhu')
在app02的urls里
	path('index/', views.index_func, name='app02_wuhu')

虚拟环境

项目1需要使用:django1.11 								 python38
项目2需要使用:django2.22 pymysql requests			      python38
项目3需要使用:django3.22 request_html flask urllib3		 python38
实际开发项目中我们只会给项目配备所需的环境,不需要的一概不配!!!

虚拟环境:能够针对相同版本的解释器创建多个分身 每个分身可以有自己独立的环境
    
pycharm创建虚拟环境:(每创建一个虚拟环境就相当于重新下载了一个全新的解释器)
命令行的方式: python -m venv pyvenv38
 
注意:python命令此处不支持多版本共存的操作 python27 python36 python38
    激活
        activate
    关闭
        deactivate

pip install --index-url http://mirrors.aliyun.com/pypi/simple/ django==1.11.11 --trusted-host mirrors.aliyun.com
posted @ 2022-12-12 20:22  可否  阅读(64)  评论(0)    收藏  举报