一.django请求生命周期流程图
# 浏览器
发送请求(HTTP协议)
# web服务网关接口:
1、请求来的时候解析封装
响应走的时候打包处理
2、django默认的wsgiref模块不能承受高并发 最大只有1000左右
上线之后会替换成uwsgi来增加并发量
3、WSGI跟wsgiref和uwsgi的关系:
WGSCI是协议
wsgiref和uwsgi是实现该协议的功能模块
# Django后端:
1、django中间件0:
类似于django的保安 门户
2、urls.py 路由层
识别路由匹配对应的视图函数
3、views.py 视图层
网站整体的业务逻辑
4、templates文件夹 模板层
网站所有的html文件
5、models.py 模型层
ORM
二.路由层之路由匹配
# 路由层也叫关系层:存储与视图层函数的对应关系
'通过对应的函数关系操作展示层的返回值'
路由匹配的特点是 只要匹配上了就会立刻结束执行对应的视图函数
#1. url方法 是正则表达式的参数
他的第一个参数其实是一个正则表达式
只要正则表达式获取用户输入的后缀匹配到了示图层的函数
那么就匹配成功
'通过url括号内第一个正则参数 可以匹配到视图内对应的函数'
url(r'^index/',views.index)
^正则的第一个
#2. 斜杠机制
用户输入了匹配名称 为加斜杠也会匹配到视图层
原因是 post请求了两次
第一次是请求失败 自动添加斜杠求'django'内置的功能
'可以取消斜杠机制'
#3. ^限制
^是正则表达式里是限制开头 $限制尾部
url(r'^index$',views.index) 这样就不会触发djago功能得自己加'/' 否则会报错
# 4.空后缀
url(r'^$',views.index) 用户不输入后缀也可以访问匹配的页面
url(r'.*',views.index) 用户不管输入什么后缀也可以访问匹配页面
三.无名有名分组
url(r'^test/([0-9]{4})/$', views.test)
'路由匹配成功之后就会调用视图函数默认情况下会自动给视图函数传递一个request位置参数'
test(request)
如果路由匹配中使用括号对正则表达式进行了分组 那么在调用视图函数的时候
会将括号内匹配到的内容当做位置参数传递给视图函数
test(request,括号内正则表达式匹配到的内容)
上述特性django称之为'无名分组'
url(r'^testadd/(?P<user_id>[0-9]{4})$', views.testadd)
给括号内的正则表达式起别名之后 匹配成功则会讲括号内匹配到的内容按照关键字参数传递给视图函数
testadd(request,user_id=括号内正则表达式匹配到的内容)
上述特性django称之为'有名分组'
# 两者混合使用
url(r'^test/(\d+)/(?P<user_id>[0-9]{4})/$', views.testadd) # 不可以
无名有名分组不能混合使用!!! 单个可以重复使用
url(r'^test/(\d+)/(\d+)/$', views.testadd) # 可以
url(r'^test/(?P<a>\d+)/(?P<b>\d+)',views.testadd) # 可以
四.反向解析
"""
a标签的href可以写网址的全称 也可以写后缀
href='https://www.baidu.com'
href='/login/' # 自动补全当前服务的ip和port
href='127.0.0.1:8000/login/'
"""
1.页面上有很多a标签链接了其他路由
2.路由匹配表达式出现了变化 html页面上的地址全部失效
# 反向解析
通过反向解析可以获取到一个结果 该结果可以访问到一个路由
步骤1:给对应关系起别名
url(r'^func666/',views.func,name='func_view')
步骤2:使用反向解析获取结果
前端:
{% url 'func_view' %} # func666/ 结果可以访问路由
后端:
from django.shortcuts import reverse
reverse('func_view') # func666/ 结果可以访问路由
# 无名分组反向解析
步骤1:给对应关系起别名
url(r'^func666/(\d+)/',views.func,name='func_view')
步骤2:使用反向解析获取结果
'''无法明确括号内正则表达式的内容 需要人为指定'''
前端:
{% url 'func_view' 123 %} # func666/123/
后端:
from django.shortcuts import reverse
reverse('func_view',args=(666,)) # func666/666/
# 有名分组反向解析
步骤1:给对应关系起别名
url(r'^func666/(?P<id>\d+)/',views.func,name='func_view')
步骤2:使用反向解析获取结果
'''无法明确括号内正则表达式的内容 需要人为指定'''
前端:
{% url 'func_view' 123 %} # func666/123/
{% url 'func_view' id=123 %} # func666/123/
后端:
from django.shortcuts import reverse
reverse('func_view',args=(666,)) # func666/666/
reverse('func_view',kwargs={'id':1}) # func666/1/
"""
疑问:无名有名反向解析中的手动传值 这个值在实际工作中到底可以是什么
一般情况下这个值可以是数据的主键值、页面的页码、区域的编号等
"""
五.路由分发
"""
如果一个django项目特别庞大 里面有很多应用 每个应用下有很多对应关系
那么django自带的路由层里面的代码就会非常非常的多 如何优化???
根据应用的不同拆分到不同的应用中
django支持每个应用都可以有自己独立的
路由层、模板层、静态文件、视图层(默认)、模型层(默认)
上述特性能够让django在分组开发上更加的方便、快捷
所有人都可以在应用中开发完整的项目功能
最后汇总到一个空的django项目中 然后通过路由分发整合所有人的应用
"""
1.创建多个应用 并去配置文件中注册
INSTALLED_APPS = [
'app01',
'app02'
]
2.在多个应用中编写相同的路由
urlpatterns = [
url(r'^index/',views.index111)
]
urlpatterns = [
url(r'^index/',views.index)
]
3.路由分发
总路由
from django.conf.urls import url, include
from app01 import urls as app01_urls
from app02 import urls as app02_urls
url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls))
"""总路由只负责分发 不负责视图函数对应"""
上述代码还可以简写
from django.conf.urls import url, include
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
六.名称空间
1.不同的应用使用了相同的别名 那么反向解析是否自动识别
index_view app01/index/
index_view app02/index/
2.验证发现默认情况下是不会自动识别应用前缀的 如何解决反向解析问题
方式1:名称空间
总路由添加名称空间
url(r'^app01/',include('app01.urls',namespace='app01')),
url(r'^app02/',include('app02.urls',namespace='app02'))
应用反向解析自动提示
reverse('app01:index_view')
reverse('app02:index_view')
{% url 'app01:index_view' %}
{% url 'app02:index_view' %}
方式2:只需要确保反向解析的别名在整个项目中不重复即可!!!
可以在别名的前面加上应用名的前缀
url(r'^index/',views.index,name='app01_index_view')
url(r'^index/',views.index,name='app02_index_view')