Django 路由层
参考文档:https://zhuanlan.zhihu.com/p/151366705
Django URL路由系统是什么
按照WSGI原理代码,所有请求都交给一个app处理,如何做到不同请求对应不同的处理?
最简单的方式就是,进入app后,不同的URL做不同的处理。也就是,建立URL和处理函数之间的映射。
路由:根据访问的路径Path不同调度不同的处理函数。可以对路径Path采用模式匹配。
Django 3.x使用path、re_path定义,这和2.x略有区别
简而言之,路由系统就是URL路径和视图函数的一个对应关系,也可以称为转发器。
路由配置
path参考:https://docs.djangoproject.com/en/3.2/topics/http/urls/#example
主目录中的urls.py是路径匹配的入口,它定义在 settings.py 中 ROOT_URLCONF = 'devops.urls' 约定,称主目录中的路由配置文件urls.py为 主路由 或 一级路由
URL路由系统格式:
# devops/urls.py
urlpatterns = [
path(regex, view, kwargs=None, name=None),
]
urlpatterns:一个列表,每一个path()函数是一个元素,对应一个视图
参数:
• regex:一个字符串或者正则表达式,匹配URL,类似于Nginx中的location
• view:对应一个函数视图或者类视图(as_view()的结果),必须返回一个HttpResponse对象,Django将这个对象转换成一个HTTP响应,类似于Nginx location中配置的proxy_pass
• kwargs:可选,字典形式数据传递给对应视图
• name:可选,URL名称,URL路径别名,一般用于前端试图模板中
路由分发
项目目录下的urls.py叫 根路由/主路由文件 应用目录下的urls.py叫 二级路由文件
如果所有路由都定义在主路由文件中,太乱太臃肿,解决的办法就是二级路由/路由分发,即路由到应用的路有文件。但是脚手架建立的应用文件中缺少urls.py,手动在应用目录建立一个。
URL路由分发好处:urls配置解耦,方便管理

示例
# 1.主路由文件
# devops/urls.py
from django.contrib import admin
from django.urls import path, include
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
# include函数,指向二级路由文件/应用路由文件
path('myapp/', include('myapp.urls')),
]
# 2.应用路由文件
# 在myapp目录下新建urls.py
from django.urls import path
from .views import index, test_index
urlpatterns = [
path("", index), # 二级路由包含前缀myapp/,对应URL是/myapp/
path("hello", test_index), #二级路由包含前缀myapp/,对应URL是/myapp/hello
]
# 3.在myapp/view.py中增加test_index视图函数
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("hello,world")
def test_index(request):
return HttpResponse("hello,test_index")
# 访问 http://127.0.0.1:8000/myapp, http://127.0.0.1:8000/myapp/hello
正则表达式匹配/分组
URL路径也可以使用正则表达式匹配,re_path()替代path()
re_path支持正则表达式,参考: https://docs.djangoproject.com/en/3.2/topics/http/urls/#using-regular-expressions
无名分组/普通分组
"""
devops/urls.py 主路由文件配置
"""
from django.contrib import admin
from django.urls import path, include, re_path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('myapp/', include('myapp.urls')),
re_path('articles/2020/$', views.specified_2020),
# 下述正则表达式会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以位置参数的形式传给视图函数,有几个分组就传几个位置参数
re_path('^articles/([0-9]{4})/$', views.year_archive),
re_path('^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
re_path('^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
"""
myapp/view.py 视图函数
"""
from django.http import HttpResponse
def index(request):
return HttpResponse("hello,world")
def test_index(request):
return HttpResponse("hello,test_index")
def specified_2020(request):
return HttpResponse("指定2020年 文章列表")
# 需要额外增加形参用于接收传递过来的分组数据
def year_archive(request, year):
return HttpResponse("%s年 文章列表" % year)
def month_archive(request, year, month):
return HttpResponse("%s年/%s月 文章列表" % (year, month))
def article_detail(request, year, month, id):
return HttpResponse("%s年/%s月 文章ID: %s" % (year, month, id))
有名分组/命名分组
当我们对分组命名后,就会按照key=value的关键字参数形式为视图函数传参
url.py
from django.contrib import admin
from django.urls import path,re_path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
# 该正则会匹配url地址的路径部分为:article/数字/,匹配成功的分组部分会以关键字参数(article_id=匹配成功的数字)的形式传给视图函数,有几个有名分组就会传几个关键字参数
# 需要强调一点是:视图函数得到的值均为字符串类型
re_path(r'^article/(?P<article_id>\d+)/$',views.article),
]
views.py文件
from django.shortcuts import render
from django.shortcuts import HttpResponse
# 需要额外增加一个形参,形参名必须为article_id
def article(request,article_id):
return HttpResponse('id为 %s 的文章内容...' % article_id)
测试
python manage.py runserver 8001 # 在浏览器输入:http://127.0.0.1:8001/article/3/ 会看到: id为 3 的文章内容...
总结
普通分组和命名分组都是为了获取路径中的参数,并传递给视图函数,区别在于普通分组是以位置参数的形式传递,命名分组是以关键字参数的形式传递。
普通分组和有名分组不要混合使用
浙公网安备 33010602011771号