DRF05-路由源码剖析

drf常用路由有两种,一种是DefaultRouter,另一种是SimpleRouter。

DefautRouter生成路由格式:

  • 1, 列表路由
  • 2, 详情路由
  • 3, 根路由
[
# 列表路由
<RegexURLPattern haha-list ^books/$>, 
<RegexURLPattern haha-list ^books\.(?P<format>[a-z0-9]+)/?$>,

# 带pk访问的详情路由
<RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)/$>, 
<RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>, 

# 根路由,访问到应用根的路由
<RegexURLPattern api-root ^$>, 
<RegexURLPattern api-root ^\.(?P<format>[a-z0-9]+)/?$>
]

请求方式一:DefautRouter+浏览器访问+无.json

请求方式二:DefautRouter+浏览器访问+.json

当我们使用DefautRouter的时候,浏览器访问有两种模式,一种是DRF提供的一套操作页面,请求url不带.json,一种是返回json数据,这种模式的请求url附带.json

请求方式三:postman+无.json

可以发现postman请求到的是json数据。

请求方式一和三的url是一样的,为何返回的结果不一样呢?这是因为浏览器中默认请求头中附带了Accept: text/html,而postman请求默认的是Accept: application/json。也就是说,DRF可以根据请求头中的信息智能返回请求的数据。

请求方式四:postman+Accept: text/html

可以看到postman接受到的就是html数据。

为什么drf会有这个DefautRouter?

因为DRF还给我们整一套了网页,可以在这个网页上直接增删查改,测试十分方便。

SimpleRouter生成路由格式:

  • 1, 列表路由
  • 2, 详情路由
[
# 列表路由
<RegexURLPattern haha-list ^books/$>, 
# 详情路由
<RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)/$>
]

DefaultRouter与SimpleRouter路由相比多了一对根路由,这个我们不常用,另外就是多了一个以什么格式返回数据的路由,例如DefaultRouter的三对路由的每一对路由的第二个都是匹配返回格式,例如.json。SimpleRouter路由最终的结果就是我们常用的五大请求。

SimpleRouter使用案例

from rest_framework.routers import SimpleRouter
#1,创建路由对象
router = SimpleRouter()

#2,注册视图集
router.register('books',views.BookInfoModelViewSet,base_name="haha")
urlpatterns += router.urls

#3,输出结果
print(urlpatterns)

前端请求展示

可以看到,使用SimpleRouter浏览器默认返回的就是可操作性页面,这个时候不支持.json的请求方式了,如果我们想得到json的数据形式,就只能在请求头中附带Accept: application/json

SimpleRouter源码解析

  1. django首先执行语句1,SimpleRouter没有register方法,显然是执行的是父类的,跳到2
  2. 标记2,register方法主要做了两件事,一个是将标记1中的路由关系存储到registry这个列表中,另一个是清除路由对象集合中的_urls属性,,也就是说,标记1可以出现多次。
  3. 标记3是获取一个路由集合,这个集合虽然来自router.urls,看起来是一个属性,实际是一个方法,标记3最终执行的是标记4的函数
  4. 标记4 这个函数首先判断路由对象中有没有_urls这个对象,很明显是没有嘛,因为标记2每次被执行都会尝试清除路由对象中的_urls这个属性,于是if判断为真,尝试执行标记5,get_urls这个函数,而SimpleRouter这个类中定义了get_urls这个方法,因此最终执行的是SimpleRouter中的get_urls,即标记6
  5. 标记6这个函数最终执行的是什么?标记7,这个方法熟悉吗?就是我们之前纯粹使用django的路由写的请求视图映射函数。

因为标记1可以执行多次,多次放入视图集类,也就是说标记6中的for循环第一层遍历的其实是视图集类,而内部第二个for循环遍历的是每个视图集类中的五个请求方法。于是乎,我们只在settings.py这个文件中写了一条语句,drf就帮我们生成了五个路由。

posted @   yaowy  阅读(270)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示