django—路由层
1、路由匹配
1、url第一个参数是一个正则表达式,只要匹配到结果,就会立即执行对应的视图函数,不再往下匹配查找
2、在匹配请求url时,若不能匹配到结果,django会让浏览器重定向,url为原来的url加上/
,如果还是匹配不到,就会返回404
3、只匹配url部分,不会匹配参数部分,如get请求携带参数?username='dadsadasd
'
基于此,一般的url正则规则是:起始符^
,加斜杠/
,结束符&
;如:
urlpatterns = [
url(r'^admin/', admin.site.urls), # 不添加结束符$,代表后面可以跟其他的url,不会限制死
url(r'^login/$', views.login), # 添加^、$符,代表只有login/能匹配到,不能多不能少
url(r'^home/$', views.home), # 这种情况下,请求home匹配不到,django重定向到home/即可匹配到
url(r'^userlist', views.userlist), # 这种情况下,请求userlistdasdad也能够匹配到,不严谨
url(r'index/$', views.index) # 这种情况下,请求asddsaindex也能匹配到
]
2、无名分组
1、url的正则匹配有分组,并且没有给它命名
2、使用分组接收多个参数时,参数时直接连在一起作为字符串进行正则匹配的,因此,传多个分组参数时,可能会出现前一个分组将第二个参数分割了,导致参数错误
3、django会将匹配到的分组内的字符串作为另外的位置参数传给视图函数,因此,对应的视图函数必须要定义位置形参或者用args
接收它。如:
# urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^edit/(\d+)/', views.edit)
]
# views.py
def edit(request,*args): # 可以接受多个位置参数,即多个正则分组
print(args)
3、有名分组
1、url的正则匹配有分组,并且给它命名
2、同样,在多个分组解析参数时,可能会出现分组内容被前一个分组分割的情况,因此正则规则的设计至关重要
3、django会将匹配到的分组内的字符串作为另外的关键字参数传给视图函数,因此,对应的视图函数必须要定义同名参数接收它或者用kwargs
接收。如:
# urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^edit/(?P<edit_id>\d+)/')
]
# views.py
def edit(request,**kwargs): # 可以接受多个位置参数,即多个正则分组
print(kwargs)
注意点:
在url路由层,不能同时使用有名分组和无名分组
4、反向解析
目的:使得在路由层之外,可以用变量引用的方式动态绑定url,便于维护,有利于程序扩展
实现:在url路由层,给url起别名,在路由层之外任何地方,可以通过这个别名解析出对应的url
根据url的正则匹配结果是否唯一来分情况处理:一般结果不唯一的部分都会被分组,所以此处按是否分组讨论
1、路由中的正则规则不包含分组
此时代表正则规则匹配结果唯一,如
url(r'^home/$', views.home,name='home') #home/ 给起别名为home
# 前端反向解析:
<p><a href="{% url 'xxx' %}">111</a></p> # 引用别名home
# 解析结果:<p><a href="home/">111</a></p>
# 后端反向解析:以视图层为例
from django.shortcuts import render,HttpResponse,redirect reverse
def xxx(request):
url = reverse('home') # 引用别名home,解析结果:/home/
return redirect(url) # 重定向到/home/
2、分组没有起别名
此时代表正则匹配结果不唯一,不唯一的部分被分组
在解析时需要手动输入一个参数使得,正则匹配分组部分也能匹配到结果如
url(r'^edit/(\d+)/',views.edit, name='edit')
# 前端反向解析:
{% url 'edit' 6666 %} # 直接写一个符合正则的字符串
# 后端反向解析:
url = reverse('edit',args=(8888,)) # 以元组的形式传入一个符合正则分组规则的字符串
3、分组有起别名
可以直接用无名分组相同的方式
可以使用正规的方式,如下:
url(r'^edit/(?P<edit_id>\d+)/',views.edit, name='edit')
# 前端反向解析:
{% url 'edit' edit_id=6666 %} # 直接写一个同分组名的关键字参数
# 后端反向解析:
url = reverse('edit',kwargs={'edit_id':8888} # 以字典的形式传入,key与分组名同名
5、 路由分发
1、路由分发的来源
1、在django中所有的app都可以有自己的独立的urls.py,templaces,static
2、基于1,可以实现多人开发,互不干扰
3、最后只需要将所有人开发的app整合到一个空的django项目中,即可完成一个大项目
4、整合设置:注册app、路由分发
2、路由分发所做的事情
整合所有app后,如果将所有的app路由层都整合到一起,那么代码将会非常长,路由匹配过度
所以,使用路由分发,总路由不再做url与视图函数的匹配工作,而是将请求分发到对应的app,由对应的app处理请求的工作
3、实现
使用include方法,实现路由分发
方式一:导入各应用的urls
# 导入app的urls,为了区分不同的app,将不同app的urls起别名
from app01 import urls as app01_urls
from app02 import urls as app02_urls
# 是使用include方法,实现路由分发
urlpatterns = [
url(r'^admin/', admin.site.urls), # url第一个参数是一个正则表达式
# 路由分发
url(r'^app01/',include(app01_urls)), # 总路由里面不能以$结尾
url(r'^app02/',include(app02_urls)),
]
方式二:利用反射的原理,加上一些模块的帮助,直接分发到app
urlpatterns = [
url(r'^admin/', admin.site.urls), # url第一个参数是一个正则表达式
# 路由分发
url(r'^app01/',include(app01.urls)), # 总路由里面不能以$结尾
url(r'^app02/',include(app02.urls)),
]
6、名称空间
当多个app的路由层取的别名相冲突时,为了保证分发到正确的应用,有两种方式做区分
# app01的urls.py
urlpatterns = [
url(r'^reg/',views.reg,name='reg')
]
# app02的urls.py
urlpatterns = [
url(r'^reg/',views.reg,name='reg')
]
方式一:给每一个app创建名称空间,如:
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 路由分发
url(r'^app01/',include(app01.urls),namespace='app01'),
url(r'^app02/',include(app02.urls),namespace='app02'),
]
# 前端反向解析:
{% url 'app01:reg' %}
{% url 'app02:reg' %}
# 后端反向解析:
url1 = reverse('app01:reg')
url2 = reverse('app02:reg')
方式二:规范起名,以app名开头
即给路由起别名的时候,就做好区分,以app名开头,如:
# app01的urls.py
urlpatterns = [
url(r'^reg/',views.reg,name='app01_reg')
]
# app02的urls.py
urlpatterns = [
url(r'^reg/',views.reg,name='app02_reg')
]
7、伪静态
搜索引擎在遇到html等静态文件时,将会收藏该文件,从而提高改页面的seo查询频率和搜藏力度
伪装方式:
# 给url起别名时,以.html等表示静态文件的方式结尾
8、虚拟环境
1、虚拟环境相当于一个python解释器
2、刚下载安装时,没有任何的模块包
3、一台机器上可以有多个
4、利用虚拟机,可以给每一个项目,只装备该项目所需要的模块,减少资源消耗
9、django版本区别
主要是django1与django2的区别
此处只谈在路由层的区别
django1用的是url方法实现路由匹配
django2用的时path方法和re_path方法实现路由匹配
django2中re_path方法与django1中的url方法,没有区别
django2中path方法与django1中的url方法的区别如下:
1、path的第一个参数不是正则,也不支持正则,些什么就匹配什么
2、path提供了5种转换器,能够将匹配到的数据转换成对应的数据类型,url没有
3、除了默认的5种转换器,还支持自定义转换器