django框架|django框架——路由层

系列文章目录 第一章 django安装与介绍
第二章 django基础使用

文章目录

  • 系列文章目录
  • 前言
  • 一、路由匹配
    • 1.路由匹配方式
  • 二、无名分组
  • 三、有名分组
  • 四、反向解析
    • 1.使用反向解析获取指定的路由
    • 2.无名分组反向解析
    • 3.有名分组反向解析
  • 五、路由分发
  • 六、名称空间

前言 上一篇文章《django基础使用》,大致演示了基础的django使用方法,接下来的内容将会详细的对路由层进行学习。但在学习之前需要了解django的请求生命周期流程图。
django框架|django框架——路由层
文章图片

一、路由匹配 路由匹配的特点是:
  • 只要匹配上了就会立刻结束执行对应的视图函数
  • url方法的第一个参数其实是一个正则表达式
  • 只要正则表达式能够从用户输入的后缀中匹配到内容就算匹配上了
1.路由匹配方式 django路由匹配再对/xxx没有匹配关系时,会在末尾加上一个斜杠再次匹配
例如:
url(r'^index/', views.index)

针对上面的路由配置,跳转到127.0.0.1/index,第一次匹配不到,会再次发送请求 127.0.0.1/index/ 此时就会配对上,然后根据视图函数返回响应。
这种二次匹配加斜杠的方式可以通过配置来关闭
APPEND_SLASH = False

由于url第一个参数是正则 所以当项目特别大 对应关系特别多的时候要格外的注意是否会出现路由顶替的现象
设置不再url后携带后缀时自动跳转(多用于跳转主页):
url(r"^$", views.index)

也可以定义一个尾页 用户输入一个没有对应关系的直接返回
url("^.*", views.error)

这样匹配不到关系会自动调用error视图函数,但这样会让一些不应该显示error页面的url也显示项目的error页面,所以不推荐使用。
注意:
路由设置中第一个参数为正则表达式,所以当路由多了之后容易造成一些跳转问题,例如:
127.0.0.1/index/ 对应主页
127.0.0.1/indexasdasdasdasd/ 也会对应到主页,但这样是不符合预期的,所有会使用$对正则进行结尾的限制。
二、无名分组 在用户输入url后,自动匹配关系,然后将设定的部分url作为参数传给视图函数。
无名分组为正则参数中不设置参数名,此时传给视图函数的参数为位置参数。
无名分组路由中的设置方式:
url("^passage/all/(\d*)/$", views.passage) # ()的设置可以是多个 #在无名分组中按照位置传递,第一个传递的为request

此时除了向视图函数传递request以外还传递了一个数字,这个数字表示了第几页。
无名分组视图层中函数的接收方式:
def passage(request, pagination): # 此时pagination中就是对应的页码 #此时为接收一个参数,也可以书写多个形参接收 ....... #当我们不知道要接收几个参数时可以使用*args来接收 def passage(request, *args): ......

三、有名分组 在用户输入url后,自动匹配关系,然后将设定的部分url作为参数传给视图函数。
有名分组为正则参数中为传递的值设置参数名,此时传给视图函数的参数为关键字参数。
有名分组路由中的设置方式:
url("^passage/all/(?P\d*)/$", views.passage) # ()的设置可以是多个 #在有名分组中按照位置传递,第一个传递的为request,后续参数为关键字参数

此时除了向视图函数传递request以外还传递了一个参数,这个参数表示了第几页。
有名分组视图层中函数的接收方式:
def passage(request, pagination): # 此时pagination中就是对应的页码,此处必须和路由中设置的名字一致 #此时为接收一个参数,也可以书写多个形参接收 ....... #当我们不知道要接收几个参数时可以使用**kwargs来接收 def passage(request, **kwargs): ......

四、反向解析 页面上有很多a标签链接了其他路由
路由匹配表达式出现了变化,html页面上的地址全部失效
这个时候可以使用反向解析获取对应的路由
1.使用反向解析获取指定的路由 1.在路由层中为指定路由设置name
url(r'^lo/', views.login, name="login_view"), url(r'^re/', views.register, name="register_view"),

2.在视图层为对应视图函数绑定reverse
from django.shortcuts import reverse def login(request): reverse('login_view')def register(request): reverse('register_view')

3.在对应需要使用路由的前端设置
这是主页 登录页面 注册页面

2.无名分组反向解析 1.在路由层中为指定路由设置name
url(r"^not/(\d*)/$", views.not_grouping, name="not_view"),

2.在视图层为对应视图函数绑定reverse
from django.shortcuts import reverse def not_grouping(request, num): reverse("not_view", args=(45,)) return HttpResponse("无名分组参数已发送")

3.在对应需要使用路由的前端设置
这是主页 文章页面,无名分组,反向解析 文章页面,无名分组,反向解析

3.有名分组反向解析 1.在路由层中为指定路由设置name
url(r"^has/(?P\d*)/$", views.has_grouping, name="has_view"),

2.在视图层为对应视图函数绑定reverse
from django.shortcuts import reverse def has_grouping(request, num): reverse("has_view", args=(65,)) # 绑定方式1 当前端调用反向解析直接传入参数值使用 args来绑定 reverse("has_view", kwargs={"num":65}) # 绑定方式2 当前端调用反向解析通过关键字参数传入时 使用kwargs来绑定 #俩种绑定方式在同一个视图函数中只能选一种 return HttpResponse("有名分组参数已发送")

3.在对应需要使用路由的前端设置
这是主页 文章页面,有名分组方式1,反向解 文章页面,有名分组方式1,反向解 {# 上方的方式一,对应reverse按照顺序参数传值时使用#} 文章页面,有名分组方式2,反向 文章页面,有名分组方式2,反向解 {# 上方的方式二,对应reverse按照关键字参数传值时使用,特别注意关键字参数编写时不能带上空格#}

五、路由分发 当一个项目特别大时,开发完毕后的路由会非常的大,管理和维护也困难,此时可以将整个项目拆解为多个app容器来各自开发,此时项目文件下的urls.py只需要集成各个app容器的路由即可。
1.在每个app容器中创建自己的urls(最好在各自app容器下创建templates、static)
django框架|django框架——路由层
文章图片

2.对应每个app容器下的路由与视图的编写
3.在项目同名文件中的路由中集成所有app容器中的路由
第一种集成方式,通过导入所有app下的路由,其中传参使用include:
from django.conf.urls import url,include from django.contrib import admin from app01 import urls as app01_urls from app02 import urls as app02_urlsurlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/',include(app01_urls)), url(r'^app02/',include(app02_urls)), ]

【django框架|django框架——路由层】第二种集成方式,直接使用注册好的app直接引入路由
from django.conf.urls import url,include from django.contrib import adminurlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/',include('app01.urls')), url(r'^app02/',include('app02.urls')), ]

六、名称空间 当多个app容器中有相同名字的路由被配置时,使用反向解析,路由分发不会分辨其app容器,而是直接使用相同名字中最后一个加载的配置作为解析结果。此时可以使用俩种方式解决该问题。
方法一:
1.在总路由(总路由指项目同名文件下的urls.py)中设置名称空间
url(r'^app01/',include('app01.urls', namespace="app01")), url(r'^app02/',include('app02.urls', namespace="app02")),

2.在对应app容器对应的路由中设置name
# app01容器下的urls url(r"^index/", views.index, name="index_view"),# app02容器下的urls url(r"^index/", views.index, name="index_view"),

3.在对应需要的视图函数中设置reverse
# app01容器下的views def index(request): reverse("app01:index_view") return render(request, "index.html") # app02容器下的views def index(request): reverse("app02:index_view") return render(request, "index1.html")

4.在对应需要使用到反向解析结果的地方使用
登录页面,反向解析 注册页面,反向解析 文章页面,无名分组,反向解析 文章页面,无名分组,反向解析 文章页面,有名分组方式1,反向解析 文章页面,有名分组方式1,反向解析 文章页面,有名分组方式2,反向解析 文章页面,有名分组方式2,反向解析

方式二:
只需要确保反向解析的别名在整个项目中不重复即可
可以在别名的前面加上应用名的前缀
# app01容器下的urls url(r"^index/", views.index, name="app01_index_view"),# app02容器下的urls url(r"^index/", views.index, name="app02_index_view"),

    推荐阅读