一.路由基础
1.路由url函数:路由自上而下进行匹配;url(正则路径,视图函数内存地址,默认参数,路由别名)
2.路由正则:
规定开始:^ | 规定结束:$ #url(r'index', view.index) 可以匹配:/index/ | /abcindex/ | /indexabc/ | /aindexb/ 均可以匹配 #url(r'^index', view.index) 可以匹配:/index/ | /indexadc/ 均可以匹配 #r'^index$' 只能匹配index,不能匹配index/ #r'^index/$' 可以匹配index和index/(先拿index匹配,如果失败,会自动添加/再次进行匹配)
默认参数:是关键字参数,在视图函数中可以通过关键字参数进行接收
urls.py #url(r'^index/$', views.index, {'num': 11}) view.py # def index(request, num): # pass
路由匹配是否会默认添加/:我们可以通过设置settings.py文件来进行修改
settings.py # 先把中间件的 'django.middleware.common.CommonMiddleware' 关闭 # 然后新增: APPEND_SLASH = False
二.有名无名分组
1.无名分组:r'^delete/(d+)/(d+)$'
# 路由:url(r'^delete/(d+)/(d+)$', views.delete) #请求路径:/delete/1/2 #视图函数:def delete(request, n1, n2): # n1=1, n2=2
2.有名分组:r'^delete/(?P<id>d+)/(?P<num>d+)$'
# 路由:url(r'^delete/(?P<id>d+)/(?P<num>d+)$', views.delete) #请求路径:/delete/1/2 #视图函数:def delete(request, id, num): # id=1, num=2 只能使用id,num来接收参数
注:路由正则不支持有名无名分组混用
三.多app共存的路由分配
1.创建多个app有三种方式:
#1.django-admin startapp app_name #2.python3 manage.py startapp app_name #3.Tools工具下的:run manage.py task...
2.在settings.py文件中配置INSTALLED_APPS,添加新建的应用:'app_name.apps.App_nameConfig'。注:app配置的顺序决定了(共同资源冲突下的)查找顺序
3.处理路由冲突
#在主路由中要配置多个app,要对视图函数调用起别名 from app01 import views as app01_views from app02 import views as app02_views url(r'^app01/test_page/$', app01_views.test_page) url(r'^app02/test_page/$', app02_views.test_page) # 如果不进行区分的话,它会自上而下进行匹配,最终匹配最后导入的views
四.多app共存时模板冲突问题
方式1:
在对应应用下建立自己的templates文件夹,再在templates下建立与应用名同名的文件夹,模板文件放在应用名同名的文件夹下。
方式2:
在项目根目录下的templates中建立每一个应用名同名的文件夹,每个应用的模板文件放在自己应用名文件夹下
#使用:render(request, 'app_name/test.html')
五.路由分发
目的:分担总路由的代码压力,将每个app的自身路由配置交给app自己的urls.py文件来管理(分文件管理路由)。
步骤:
1.在每一个应用中建立自身的urls.py文件,语法同主路由
2.在主路由中进行分发:
#主路由: from django.conf.urls import include urlpatterns = [ url(r'^app01/', include('app01.urls')), url(r'^app02/', include('app02.urls')), ] #注:主路由分发一定不能使用$正则语法,因为后面还要跟子路由的路径 #子路由(app01): urlpatterns = [ url(r'^login/$', views.login) ]
六.路由别名
''' 1.有些路由会被大量访问(直接访问、间接访问) 2.这些路由可能后期还会发生变化 3.可以给路由设置别名,通过别名访问:<a href="{% url '路由别名' '传入有名无名分组所需参数' %}"></a> ''' # url(r'^index1/(?P<id>d+)$', views.index, name='index') # 通过别名访问:<a href="{% url 'index' 1 %}"></a>
七.名称空间
''' 主路由: from django.conf.urls import include urlpatterns = [ url(r'^app01/', include('app01.urls', namespace='app01')), url(r'^app02/', include('app02.urls', namespace='app02')), ] app01应用下路由 from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^test/', views.test, name='test') ] app02应用下路由 from django.conf.urls import url from app02 import views urlpatterns = [ url(r'^test/', views.test, name='test') ] 前端页面反向解析:{% url 'app01:test' %} | {% url 'app02:test' %} 视图函数reverse方法:url = reverse('app01:test') | url = reverse('app02:test') '''
八.反向解析
''' from django.shortcuts import reverse 在视图函数中通过reverse方法反向解析出真实的路径 # 1.不带分组:url(r'可能会变的真实路由', 视图函数, name='路由别名') url = reverse('路由别名') # 2.无名分组:url(r'可能会变的真实路由(带无名分组)', 视图函数, name='路由别名') url = reverse('路由别名', args=(给无名分组赋值)) # 3.有名分组:url(r'可能会变的真实路由(带有名分组)', 视图函数, name='路由别名') url = reverse('路由别名', kwargs={给有名分组赋值,key就是有名分组名})
九.2.x新特性
''' from django.urls import path, re_path # 2.x版本 from django.conf.urls import url # 1.x版本,向下兼容,但不建议使用 urlpatterns = [ path('admin/', admin.site.urls), ] # 1. 2.x版本re_path的使用方式同1.x版本url # 2. path写的是绝对字符串,请求地址必须与路由地址完全匹配 # 3. path拥有五个转换器: -- str:匹配除路径分隔符(/)外的字符串,默认 -- int:匹配自然数 -- slug:匹配字母、数字、横杠及下划线组成的字符串 -- uuid:匹配uuid形式的数据 -- path:匹配任何字符串,包括路径分隔符(/) (不能用?) '''
十.自定义转换器
''' # 原因:自定义正则匹配目标路径 语法: 1.自定义类 # 匹配11位的185电话 class CVT185phone: # 匹配过程 regex = '185d{8}' def to_python(self, value): return int(value) # 反解过程 def to_url(self, value): return '%11d' % value # 在主路由中 from django.urls import register_converter from 所在路径 import CVT185phone register_converter(CVT185phone, 'phone185') path('page/<phone185:msg>/', views.page, name="pages") '''