1.Django的请求生命周期流程
1.从前端入手 前端发送请求
2.wsgiref 模块上对 Request 请求进行分装
3.经过Django框架的中间件
4.Django框架上的 路由映射 urls.py 去根据路径映射制定的视图函数
5.Django框架上的 视图函数 views.py 中去模板层渲染前端 或者去模型层modesl.py 做一些后端操作或者orm操作数据库
6.Django框架上的 urls.py 根据制定路径回去
7.回到了 wsgiref 模块上 对Django的 response 对象进行封装
基本上就是这样的流程 可以根据图片来理解记忆
2.路由层
1..路由匹配的
Url方式的第一个参数就是一个正则表达式
只要正则表达式能从用户输入的后缀能匹配到内容就行
这是在我们创建app下的view.py文件下写的
# 做了两格视图函数
'''
def aaa(request):
return HttpResponse("aaa")
def bbb(request):
return HttpResponse("bbb")
'''
然后在我们总的项目下的urls.py下创建路由
# 做了两个路由
'''
path('aaa/', aaa),
path('aaaa/',bbb),
'''
然后我们访问aaa的路由就能看到我们页面打印aaa了 注意要在urls下引用我们视图函数创建的aaa函数
正则的话有些不一样我门访问aaaa的接口话匹配到的还是aaa
# 用 path 语法写接口
# aaaa 匹配到的是 bbb
# 用正则规则写
'''
re_path(r'^aaa', aaa),
re_path(r'^aaaa', bbb),
'''
'''
路由匹配 http://localhost:8000/aaaa/
# aaa
# 正常的结果应该是 bbb
'''
# 解决办法 /
# / 是路径的结束符 只有遇到 / 才认为当前的请求路径结束
re_path(r'^aaa/', aaa),
re_path(r'^aaaa/', bbb),
或者直接
path('aaa/', aaa),
path('aaaa/',bbb),
'''
演变过程
正则是test/ 内容是test 那么首次无法匹配
django二次追加斜杠机制
首次匹配不上 那么django还会让浏览器默认加斜杠再次发送请求
test 301
test/ 200
斜杠机制可以取消 但是不推荐
在setting里面
APPEND_SLASH = False
3.无名有名分组
url(r'^test/([0-9]{4})/$', views.test)
数字0-9 任意四个数字就行
url(r'^test/(\d+)/$', views.test)
有括号的话 就是把我输入的四个数字当作内容文本传这个视图函数的内容
我们可以把在路由输入的数字传入到后端来
给括号内的正则表达式起别名之后 匹配成功则会讲括号内匹配到的内容按照关键字参数传递给视图函数
testadd(request,user_id=括号内正则表达式匹配到的内容)
上述特性django称之为'有名分组
# 【3】Django 2 + 取消了无名分组 只有有名分组
'''
# 有一个路径参数 是int 类型 后端接受的时候必须交 pk
path("you_name/<int:pk>/",you_name),
def you_name(request, *args, **kwargs):
print(args) # ()
print(kwargs) # {'id': '1'}
return HttpResponse("you_name")
'''
4.反向解析
1.无名反向解析
不管我上面输入的路由怎么变 在我前端的页面我只需要他name的值 就能访问到这个函数
步骤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/
2.有名反向解析
步骤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/
"""
疑问:无名有名反向解析中的手动传值 这个值在实际工作中到底可以是什么
一般情况下这个值可以是数据的主键值、页面的页码、区域的编号等
"""
5.路由分发
如果一个django项目特别庞大 里面有很多应用 每个应用下有很多对应关系
那么django自带的路由层里面的代码就会非常非常的多 如何优化???
根据应用的不同拆分到不同的应用中
django支持每个应用都可以有自己独立的
路由层、模板层、静态文件、视图层(默认)、模型层(默认)
上述特性能够让django在分组开发上更加的方便、快捷
所有人都可以在应用中开发完整的项目功能
最后汇总到一个空的django项目中 然后通过路由分发整合所有人的应用
app1下的urls.py
from django.contrib import admin
from django.urls import path
from app1.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', index),
]
app2下的urls.py
from django.contrib import admin
from django.urls import path
from app2.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', index),
]
总的urls.py
from django.contrib import admin
from django.urls import path,include
from app1 import urls as app1_urls
from app2 import urls as app2_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('app1/',include(app1_urls)),
path('app2/',include(app2_urls)),
]
# 上述代码还可以简写
from django.conf.urls import url, include
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
6.名称空间
总的ulrs.py
from django.contrib import admin
from django.urls import path, include
from app1 import urls as app1_urls
from app2 import urls as app2_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('app1/', include((app1_urls, 'app1'), namespace='app1')),
path('app2/', include((app2_urls, 'app2'), namespace='app2')),
]
app1下的ulrs.py
app_name = 'app1'
urlpatterns = [
path('index/', index, name='app_index'),
]
app2下的ulrs.py
app_name = 'app2'
urlpatterns = [
path('index/', index, name='app2_index'),
]
app1下的view.py
def index(request):
print('app1下的:', reverse('app1:app_index'))
return HttpResponse('APP1 1111')
app2下的view.py
def index(request):
print('app2下的:',reverse('app2:app2_index'))
return HttpResponse('Hello World!')