django之路由层
django请求生命周期流程图
特别注意:WSGI是协议,而wsgiref与uwsgi是基于WSGI协议实现的功能
django路由层
1.路由匹配
django2.x及以上 path第一个参数写什么就匹配什么
django1.x 第一个参数是正则表达式
无论什么版本django都自带加斜杠后缀的功能,也可以取消
配置文件中 APPEND_ALSSH=False
2.转换器
正常情况下很多网站都会有很多相似的网址,如果我们每一个都单独开设路由不合理
django2.x及以上版本路由由动态匹配的转换器(5种)
str:匹配除路径分隔符外的任何非空字符串
int:匹配0或者任意正整数
slug:匹配任意一个有字母或者数据组成的字符串
uuid:匹配格式化后的uuid
path:能够匹配完成url路径
ps:还支持自定义转换(自己写正则表达式匹配更加细化的内容)
# 转化器,将对应位置匹配到数据转换成固定的数据类型
path('inner/<str:info>', views.inner)
# inner(实参:request对象,实参:info='转换器匹配到的类型转换之后的内容')
注意:这里是关键字传参:str后面的什么名字,对应在views函数的实参就要写什么名字
对应函数参数写法
def inner(request, info):
return HttpResponse('这里是inner页面')
path('index/<str:info>/<int:id>/', views.index_func) # index_func(实参request对象,info='转换器匹配到的类型转换之后的内容',id='转换器匹配到的类型转换之后的内容')
对应函数参数写法:
def inner(request, info, id):
return HttpResponse('这里是inner页面')
3.正则匹配
django2.x及以上版本有re_path 第一个参数是正则
匹配的本事是只要第一个正则表达式能够从用户数据的路由中匹配到数据就算匹配成功,会立刻停止路由层其他的匹配直接执行对应的视图函数
from django.urls import path,re_path
re_path('text',views.text),
re_path('textadb', views.textadb)
可以修改为:
re_path('^text/$',views.text), ^表示开始,$表示结束
re_path('^textadb/$', views.textadb)
" 注意:这里是不需要额外传参的"
django1.x路由匹配使用的url() 功能与django2.x以及以上的re_path()一致
4.正则匹配的无名与有名分组
无名分组
re_path('^text/(\d{4})', views.text)
"表示匹配已text开头,再匹配4个数字"这个时候括号内正则匹配到的内容会被当做位置参数传递给视图函数
代码如下:
def text(request,aaa): # 这里的形参是什么名字无所谓,按照位置传参
print(aaa) # 2131
return HttpResponse('这里是text')
有名分组:
re_path('^text/(?P<id>\d{4})', views.text)
"同样表示匹配text开头,再匹配4个数字,但是起了个名字id"这样会将括号内正则匹配到的内容当做关键字参数传递给视图函数
代码如下:
def text(request, id): # 如果参数写的不是id会报错,关键字传参
print(id) # 2131
return HttpResponse('这里是text')
反向解析
通过一个名字可以反向解析出一个结果,该结果可以访问到某个对应的路由
基本使用
1.路由匹配关系起别名
path('text/', views.text, name='text_func')
这样在前端页面使用的时候,就可以直接使用别名
2.反向解析语法
html页面上模板语法{% url 'text_func' %}
后端语法 reverse('text_func')
动态路由的反向解析
path('text/<str:others>/', views.text, name='text_func')
html页面上的模板语法:
{% url 'text_func' 'jason'%} 需要指定动态部分的内容
后端语法:
reverse('text_func',args=('嘿嘿嘿')) 同样也需要指定动态部分的内容
路由分发
django支持每个应用都可以用自己独立的路由层、静态文件、模板层,基于该特性多人开发项目就可以完全整合,之后利用路由分发还可以整合到一起
多个应用都有很多路由与视图函数的对应关系,这个时候可以拆分到各自的路由层中
使用路由分发前,总路由直接参与路由与视图函数的匹配
path('index/',views.index)
使用路由分发后,总路由只按照应用名分配匹配方向
path('index/',views.include('app01,urls'))
名称空间
路由分发之后,针对相同的别名默认情况下是无法识别应用前缀的
如果想要正常区分有两种方式:
方式1:名称空间
总路由
path('app01/',include(('app01.urls','app01'),namespace='app01')),
path('app02/',include(('app02.urls','app02'),namespace='app02')),
关键字参数:namespace=应用名
方式2:别名不冲突即可
多个应用别名不冲突可以使用应用名作为别名的前缀
path('index/', views.index, name='app01_index_view')
path('index/', views.index, name='app02_index_view')
虚拟环境
项目1需要使用:django1.11 python38
项目2需要使用:django2.22 pymysql python36
实际开发项目中我们只会给项目配备所需的环境,不需要的一概不配,也就是除了我们需要的模块,其他的都不下载!!!
虚拟环境:能够针对相同版本的解释器创建多个分身,每个分身可以有自己独立的环境
pycharm创建虚拟环境:(每创建一个虚拟环境就相当于重新下载了一个全新的解释器)
命令行的方式:python -m venv 文件名
注意:python命令创建虚拟环境是不支持多版本共存的,会默认创建系统环境变量最上面的解释器的虚拟环境
激活虚拟环境:
activate
关闭虚拟关键:
deactivate
下载django命令:
pip install --index-url http://mirrors.aliyun.com/pypi/simple/ django==1.11.11 --trusted-host mirrors.aliyun.com