一、Django的路由系统
1、urls.py路由文件
URL路由在Django项目中的体现就是urls.py文件,这个文件可以有很多个,但绝对不会在同一目录下。实际上Django提倡项目有个根urls.py,各app下分别有自己的一个urls.py,既集中又分治,是一种解耦的模式; urls.py文件: from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), ] 注意: 1.urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。 2.若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。 3.不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^admin 而不是 ^/admin。 4.每个正则表达式前面的'r' 是可选的但是建议加上。
2、无名分组
将加括号的正则表达式匹配到的内容当做位置参数自动传递给对应的视图函数; 如:url(r'^test/(d+)/',views.test), # 匹配一个或多个数字 ##views.py## def test(request,xxx): print(xxx) return HttpResponse('test') 这里的xxx就是test/路径后面的数字(当然正则匹配到的字符串类型的数字)
3、有名分组
将加括号的正则表达式匹配到的内容当做关键字参数自动传递给对应的视图函数; 如:url(r'^test/(?P<year>d+)/',views.test), # 匹配一个或多个数字 ##views.py## def test(request,year): print(year) return HttpResponse('test') 这里的year就是一个关键字,两处必须一样;
注意:
无名分组和有名分组不能混合使用,但是支持用一类型多个形式匹配; 无名分组多个: url(r'^test/(d+)/(d+)/',views.test), 有名分组多个: url(r'^test/(?P<year>d+)/(?P<xxx>d+)/',views.test),
4、反向解析
反向解析的本质:就是获取到一个能够访问名字所对应的视图函数;
views.py文件中导入reverse模块: from django.shortcuts import reverse 如:url(r'^index6668888/$',views.index,name='index') 1.可以给每一个路由与视图函数对应关系起一个名字 2.这个名字能够唯一标识出对应的路径 3.注意这个名字不能重复是唯一的 前端使用: {% url '你给路由与视图函数对应关系起的别名' %} 如:{% url 'index' %} 后端使用: reverse('你给路由与视图函数对应关系起的别名') 如: reverse('index')
无名分组反向解析:
后端使用: url(r'^test/(d+)/',views.test,name='list') def test(request,xxx): print(xxx) #输出的就是(d+)匹配的数字 print(reverse('list',args=(xxx,))) #list所标识的路径 return HttpResponse('test') 前端使用: {% url 'list' 10 %} #手动固定参数为10 #比如在编辑的时候,可以把参数设定为某些数据的id,就无需在使用get传递id #举例 前端语法: {%for user_obj in user_list%} <a href='edit/{{ user_obj.pk }}/'></a> {% endfor %} 视图函数: from django.shortcuts import reverse,render def edit(request,edit_id): url = reverse('edit',args=(edit_id,)) return render(request,'edit.html',locals()) #如果不用locals下面取不到edit_id 模板: {% utl 'edit' edit_id}
有名分组反向解析:
后端使用: url(r'^test/(?P<year>d+)/',views.test,name='text'), # 匹配一个或多个数字 def test(request,year): print(year) print(reverse('text',args=(10,))) #有名无名皆可使用 #或者print(reverse('text',kwargs={'year':10})) return HttpResponse('test') 前端使用: {% url 'text' 10 %} #上面这种有名分组和无名分组都可以使用 {% url 'text' year=10 %} 总结:针对有名和无名分组的反向解析统一采用一种格式即可: 后端 reverse('text',args=(10,)) # 这里的数字通常都是数据的主键值 前端 {% url 'text' 10 %}
5、路由分发
Django项目每一个app下面都可以有自己的urls.py路由层,templates文件夹,static文件夹
当项目过多的时候,把所有的路由全部放在项目的url.py文件是不明智的,因为太多容易出现混乱情况;
所以:
项目名下urls.py我们统称为总路由,它不再做路由与视图函数的匹配关系而是做路由的分配工作
然后分配到各个app中的url.py文件去做路由与视图函数关系的工作。
# 路由分发 注意路由分发总路由千万不要$结尾 from django.conf.urls import url, include # 导入一个include模块 from django.contrib import admin url(r'^app01/',include('app01.urls')), # 注意是字符串格式 url(r'^app02/',include('app02.urls')), # 注意是字符串格式 # 在应用下新建urls.py文件,在该文件内写路由与视图函数的对应关系即可 from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^index/',views.index) ]
6、名称空间
名称空间知识作了解; 在路由分发的时候为每一个app的路由分配一个名称空间: url(r'^app01/',include(app01_urls,namespace='app01')), url(r'^app02/',include(app02_urls,namespace='app02')) app01.urls.py from django.conf.urls import url from app01 import views urlpatterns = [url(r'^index/',views.index,name='index')] app02.urls.py from django.conf.urls import url from app02 import views urlpatterns = [url(r'^index/',views.index,name='index')] app01.views.py reverse('app01:index') app02.views.py reverse('app02:index')
注意:
在项目中,路由中的name=''一般都会在前缀加上app01_index,app02_index来区分,也就是加上app的名字,所以不会出现重复混乱情况,这时候再用名称空间的操作就非常的鸡肋;
二、伪静态网页
url(r'^index.html',views.index,name='app01_index') 就是加上.html后缀,本质上它还是一个动态网页,这是要直接访问也需要带上.html,但是通常来说都是利用反向解析访问,这也是对网页的一种优化,有利于搜索引擎的收录;
三、虚拟环境
1、虚拟环境
为不同的项目配置不同的版本Python解释器以适应不同项目的Python解释器版本需求以及其支持的第三方模块,提高项目的效率,去除不必要的模块导致项目的加载的速度减慢。
使用虚拟环境,会得到一个不带任何第三方包的“干净”的Python虚拟环境,已经安装到系统Python环境中的所有第三方包都不会复制过来。
当需要安装该环境所需要的包时,在设置—项目—Project Interpreter中点右上角的加号,搜索包名称后点击Install Package即可。
2、Django1.0和Django2.0的区别
django2.0里面的path第一个参数不支持正则,你写什么就匹配,100%精准匹配; 其实Django2.0也可以像Django1.0一样写路由匹配,django2.0里面的re_path对应着django1.0里面的url; 虽然django2.0里面的path不支持正则表达式,但是它提供五个默认的转换器; str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式 int,匹配正整数,包含0。 slug,匹配字母、数字以及横杠、下划线组成的字符串。 uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。 path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?) 自定义转换器 1.正则表达式 2.类 3.注册 # 自定义转换器 class FourDigitYearConverter: regex = '[0-9]{4}' def to_python(self, value): return int(value) def to_url(self, value): return '%04d' % value # 占四位,不够用0填满,超了则就按超了的位数来! register_converter(FourDigitYearConverter, 'yyyy') PS:路由匹配到的数据默认都是字符串形式