请求生命周期流程图

django请求生命周期流程图

路由层之路由匹配

我们都知道,路由层是匹配对应关系用的,那么它是怎么匹配上的呢?

urlpatterns = [
url(r'^index/', views.index),
]

url方法的第一个参数其实是一个正则表达式,只要用户输入的地址后缀与内容匹配上,就会执行对应的视图函数。

并且django有一个二次追加斜杠机制,如果你在输入地址后缀时末尾没有加斜杠,django会先匹配一次,如果匹配不上,那么django还会让浏览器默认加斜杠再次发送请求,比如:

# 第一次匹配
http://127.0.0.1:8000/index # 匹配不上加斜杠再次发送请求
http://127.0.0.1:8000/index/

如果想要取消这个斜杠机制,那么可以在settings.py加上:

APPEND_SLASH = False

因为是正则表达式,所以比如像上述代码中的例子,我在地址栏输入:

http://127.0.0.1:8000/index/abcde/66

或者:

http://127.0.0.1:8000/index/

都是可以匹配到正则:^index/ 的

拓展

让用户不需要输入地址后缀就可以访问到指定页面:

urlpatterns = [
url(r'^$', views.index),
]

也可以定义一个尾页, 用户输入一个没有对应关系的直接返回:

urlpatterns = [
url(r'.*',views.error),
]

无名有名分组

无名分组

我们都知道,路由匹配成功之后就会调用视图函数,并且默认情况下会自动给视图函数传递一个request位置参数。

但是如果正则表达式中加了括号,那么就不止传递一个request位置参数了,还会传递括号内正则表达式匹配到的内容。

urlpatterns = [
url(r'^index/(.*)', views.index),
]

如果正则加了一个括号,那么视图函数就需要多写一个形参用于接收匹配到的内容,不然会报错。

def index(request, aa):
return HttpResponse(aa)

这个就是无名分组。

有名分组

python中的正则表达式加括号是可以给括号内的内容进行命名的,这里的正则表达式自然也可以。

给括号内的内容命名为address:

urlpatterns = [
url(r'^index/(?P<address>.*)', views.index),
]

给括号内命名后,视图函数就需要一个名字相同的形参接收:

def index(request, address):
return HttpResponse(address)

这个就是有名分组。

补充说明

1.无名分组需要一个形参接收括号内的内容,名字随意。

2.有名分组也需要一个形参接收括号内的内容,名字要与正则表达式里的名字相同。

3.无名分组是位置传参,有名分组是关键字传参。

4.无名分组与有名分组不能混合使用,单个可以重复使用。

反向解析

前言:html中a标签的href可以写网址的全称,也可以写后缀,写后缀会自动补全当前ip和port。

<a href='index'>点我跳转index</a>
<!--href='127.0.0.1:8000/index' -->

如上述标签可以跳转到127.0.0.1:8000/index,但是如果我路由匹配表达式出现了变化,那么这个地址就无法跳转到我想要的页面了,比如:

# 原本
url(r'^index/', views.index)
# 修改后
url(r'^index123/', views.index)

这个时候a标签就失效了,这该如何解决呢?反向解析就可以解决这个问题。

反向解析

通过反向解析可以获取到一个结果,该结果可以访问到一个路由。这么说可能有点模糊,我们来看实战:

第一步:给对应关系起别名

url(r'^index/', views.index, name='index_view')

第二步:使用模板语法修改a标签

<a href="{% url 'index_view' %}">点我跳转index</a>

这个时候随意修改路由的匹配表达式都会不出现a标签无法跳转。

后端也可以查看‘index_view’对应的路由:

from django.shortcuts import reverse
reverse('index_view') # 对应路由

根据这个路由,我们也可以进行重定向:

from django.shortcuts import reverse
def index(request):
return redirect(reverse('index_view'))

无名有名分组反向解析

无名分组反向解析

如果你在设置路由时使用了无名分组,那么你括号内的正则表达式的内容,需要人为指定。比如如下路由:

url(r'^index/(.*)', views.index, name='index_view')

这时候你的a标签需要指定内容,因为对于表达式 '^index/(.*)' 有多种方式匹配到,a标签不知道该使用哪个,所以需要人为指定。

比如我指定括号内的内容为:123

<a href="{% url 'index_view' 123 %}">点我跳转index</a>

后端也需要指定:

from django.shortcuts import reverse
reverse('index_view', args=(123,)) # /index/123

有名分组反向解析

如果你在设置路由时使用了有名分组,那么同理,需要人为指定内容。

路由:命名为address

url(r'^index/(?P<address>.*)', views.index, name='index_view')

a标签:设置address为123,两种方式都可

<a href="{% url 'index_view' 123 %}">点我跳转index</a>
<a href="{% url 'index_view' address=123 %}">点我跳转index</a>

后端:两种方式都可

from django.shortcuts import reverse
reverse('index_view', args=(123,)) # /index/123
reverse('index_view', kwargs=('address':123)) # /index/123

路由分发

如果一个django项目特别庞大,里面有很多应用,每个应用下有很多对应关系,这种情况如果把路由对应关系都写在项目同名文件夹下的urls.py文件下是明显不合理的,所以我们要把路由对应关系拆分开。

django支持每个应用都可以有自己独立的路由层、模板层、静态文件、视图层(默认)、模型层(默认)。

每个应用编写好自己的功能后,最后只需要整合一下就可以了。并且防止出现不同应用中出现相同路由,可以通过应用前缀区分,并且用到一个include方法:

总路由:整个应用app01与app02

from django.conf.urls import url, include
# 导入各个应用的路由,并起别名方便使用
from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
url(r'^app01/', include(app01_urls)),
url(r'^app02/', include(app02_urls)),
]

简写:

from django.conf.urls import url, include

urlpatterns = [
url(r'^app01/', include('app01.urls')),
url(r'^app02/', include('app02.urls')),
]

此时,访问应用app01下的index就需要这么输入:

http://127.0.0.1:8000/app01/index/

名称空间

不同的应用,设置路由时可能会使用相同的别名,比如:

应用app01路由:

urlpatterns = [
url(r'^index/', views.index, name='index_view'),
]

应用app02路由:

urlpatterns = [
url(r'^index/', views.index, name='index_view'),
]

a标签:

<a href="{% url 'index_view' %}">点我跳转index</a>
<a href="{% url 'index_view' %}">点我跳转index</a>

此时我就无法让我的a标签都可以跳到应用app01下index或者应用app02下index,它只能跳转到其中一个。

解决方法

方法一:总路由添加名称空间

urlpatterns = [
url(r'^app01/', include('app01.urls', namespace='app01')),
url(r'^app02/', include('app02.urls', namespace='app02')),
]

a标签:

<a href="{% url 'app01:index_view' %}">点我跳转index</a>
<a href="{% url 'app02:index_view' %}">点我跳转index</a>

方式二:应用路由起别名加上应用前缀,如

urlpatterns = [
url(r'^index/', views.index, name='app01_index_view'),
]

从根本解决问题。

最新文章

  1. 使用属性动画 &mdash; Property Animation
  2. [已解决] 快速理解RSA算法
  3. Javascript 方法大全
  4. Java遍历Map的3种方式
  5. JDBC专题
  6. android ListView中button点击事件盖掉onItemClick解决办法
  7. jquery设置元素readonly和disabled(checkbox只读)
  8. cocos2d-x lua 触摸事件
  9. android3.2以上切屏禁止onCreate()
  10. HDU-4902 Nice boat
  11. crm2011js操作IFRAME和选项集
  12. android进度条
  13. [转] iOS ABI Function Call Guide
  14. 学习Lua setmetatable Lua 元表
  15. LinkeList 特有方法
  16. Starting MySQL....The server quit without updating PID file[失败]/lib/mysql/ip12189.pid). 错误一例
  17. 数据结构(六)查找---多路查找树(B树)
  18. Expo大作战(十三)--expo如何自定义状态了statusBar以及expo中如何处理脱机缓存加载 offline support
  19. Arduino入门笔记(2):Arduino的开发和virtualbreadboard仿真环境
  20. C++ Primer读书笔记(2)

热门文章

  1. 付费漫画下载、付费韩漫下载、漫画VIP下载、VIP韩漫下载哪里下
  2. 驳《我不是很懂 Node.js 社区的 DRY 文化》
  3. 将子分支代码merge到主分支master分支
  4. 将本地项目上传到gitLab操作
  5. Python知识结构
  6. Spring-AOP底层实现
  7. 不用关闭重启cad及不用更改快捷方式或者版本号c#调试cad插件
  8. drf过滤和排序及异常处理的包装
  9. GIL全局解释器锁、协程运用、IO模型
  10. python黑帽子(第五章)