Django-路由层
Django-路由层
路由的本质
本质就是通过URL告诉后端去调用哪一个逻辑函数
from django.urls import path
urlpatterns = [
path('articles', views.special),
]
articles这个路由对应着视图函数中special这个方法,浏览器输入这个链接,就会响应到special这个函数来执行
路由配置的参数
from django.conf.urls import url
urlpatterns = [
url(正则表达式, views视图函数,参数,别名),
]
- 正则表达式:一个正则表达式字符串
- views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
- 参数:可选的要传递给视图函数的默认参数(字典形式)
- 别名:一个可选的name参数
几种路由设置
url(r'text/',views.text) 只要url含有text/
url(r'^text/',views.text) 开头是text/的
url(r'^text/$',views.text) 绝对匹配
url(r'^$',view.shouye) 首页
url(r'',view.weiye) 可以用作404界面,注意这个要放在最后,否则会中途拦截
路由匹配规律
1.url第一个参数是一个正则表达式
2.一旦匹配上就立即执行,不在往下匹配
3.url全部匹配不上,就加/再次来匹配,匹配到就在内部重定向(会有两个请求)
但是不能有url(r'',view.weiye)这个,这个会匹配所有
路由自动加/的操作
settings
APPEND_SLASH=False #默认为True自动加/
有名分组和无名分组
无名分组-位置参数
urls.py
url(r'^test/(\d+)/', views.test3),
#位置参数传参,接收的数据为str
def test3(request,zx):
return HttpResponse(zx)
http://127.0.0.1:8000/test/2/
2
(\d+)可以传参,会将括号内匹配到的内容当做位置参数传递给视图函数 text(request,args)
有名分组-关键字传参
urls.py
url(r'^test2/(?P<zx>\d+)/', views.test4),
#关键字参数传参,接收的数据为str
def test4(request,zx):
print(type(zx))
return HttpResponse(zx)
http://127.0.0.1:8000/test2/23/43353
23
注意
无名和有名不能结合使用!
同种类型可以一起使用!!
url(r'^test/(\d+)/(\d+)/', views.test),
url(r'^test/(?P<xxx>\d+)/(?P<month>\d+)/', views.test),
反向解析
和静态资源的方式类似,把相同的请求名统一,修改项目的url,影响到所有前端界面的url
基础版本
http://127.0.0.1:8000/authors/
url(r'^authors/',views.author,name='zx'),
前端:<a href="{% url 'zx'%}">333333333333333333</a>
后端:url = reverse('zx')
print(url)
/authors/
高级版本
无名+反向解析
http://127.0.0.1:8000/test/12/
url(r'^test/(\d+)/', views.test3,name='xx'),
<a href="{% url 'xx' 12%}">333333333333333333</a>
url = reverse('xx',args=(12,))
print(url)
/test/12/
有名+反向解析
http://127.0.0.1:8000/test2/10/
url(r'^test2/(?P<zx>\d+)/', views.test4,name='wl'),
url = reverse('wl',kwargs={'zx':10})
print(url)
/test2/10/
路由分发
解决什么问题
当有大量app时,难以管理
怎么解决
项目urls作为中转站,负责将请求分发到不同的app中,在不同app中完成url和资源的交流
app自己管理部分资源文件(static,templates,url),这样每个app的独立性更强
要导包
import app01
url(r'app01/',include(app01.urls))
不用导包
底层使用import importlib实现
url(r'app01/',include('app01.urls'))
名称空间
解决多个app别名相同
解决方案一
url(r'^app01/',include('app01.urls',namespace='app01'))
url(r'^app02/',include('app02.urls',namespace='app02'))
print(reverse('app01:index'))
print(reverse('app02:index'))
{% url 'app01:index'%}
{% url 'app02:index'%}
解决方案二-推荐
起别名的时候,让不同app区别出来
url(r'^index/',views.author,name='app01_index'),
url(r'^index/',views.author,name='app02_index'),
伪静态
把动态界面伪装成静态网页,提高搜索引擎查询的优先级(把看上去像静态网页的优先收录)
虚拟环境
通常针对不同的项目只会按照该项目所用到的模块,用不到的一概不装
不同的项目对应有专门的解释器环境与之对应
每创建一个虚拟环境就类似于重新下载了一个纯净的python解释器
会有一个叫requirements.txt文件,该文件列出来的是一个个该项目需要用到的模块名和版本号,直接运行命令可以自动下载安装相关的模块
1.x和2.x的区别
django1.x
django2.x
urls.py中1.x用的是url,而2.x用的是path
并且2.x中的path第一个不支持正则表达式,写什么就匹配什么
如果你觉得不好用,2.x里面还有re_path 这个re_path就是你1.x里面的url
提供5个默认转换器还可以自定义转换器