路由层 分组 反向解析 路由分发 名称空间 2.0和1.0差别

django请求的生命周期

 一、路由层

(django2.0中路由层使用的是path,不是url,见手撸御姐系列)

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'', views.home),  #这样写完蛋了,你输入什么都走这个了,其他接口永远别想走
    url(r'^$', views.home),  #这样才是主页,127.0.0.1:8000会跳到这里
    url(r'test/', views.test), #这样写只要字符串中有test四个字都会跳到这里,如xxxtest,testadd
    url(r'^test/', views.test), #只要test/开头都会跳到这里,如test/xxxooo
    url(r'^test/$', views.test), #这样就只能是test/才能访问
    url(r'^testadd/', admin.testadd), #testadd也可以访问这里,从上至下匹配不到,系统会自动加上/再来找一次(前提是没有被上面的test半路抢劫)
知识兔
1. url()方法 第一个参数 其实是一个正则表达式,请求来了会从上往下进行匹配,一旦前面的正则匹配到了内容 就不会再往下继续匹配 而是直接执行对应的视图函数

2. 正是由于上面的特性 当你的项目特别庞大的时候 url的前后顺序也是你需要你考虑,极有可能会出现url错乱的情况,后面的被前面的半路抢劫

3.django在路由的匹配的时候如果浏览器中没有敲最后的斜杠,django会先拿着你没有敲斜杠的结果去从上往下匹配,
   如果都没有匹配上,会自动在末尾加斜杠再发一次请求 再匹配一次,匹配上了就调用视图函数,如果还匹配不上才会报错     如果你想取消该机制,不想二次匹配可以在settings配置文件中 指定:                                  APPEND_SLASH
= False # 该参数默认是True,通常不这样干,都想省事嘛
知识兔

二、有名分组和无名分组、反向解析

1.参数传递

1.无名分组
    url(r'^test/([0-9]{4})/', views.test)
    路由匹配的时候 会将括号内正则表达式匹配到的内容 当做位置参数传递给视图函数,即视图函数除了接收request参数外还要接收一个额外参数,名字随便
    例如:test(request,xxx)——> test(request,1234)

知识兔
2.有名分组    url(r'^test/(?P<year>\d+)/', views.test) #?P<名字>  是给正则\d+起名字叫year    路由匹配的时候 会将括号内正则表达式匹配到的内容 当做关键字参数year=1234传递给视图函数,即视图函数除了接收request参数外还要接收一个额外关键字参数year    test(request,year))——> test(request,1234)
3.不能混用
#
无名有名不能混合使用 !!!url(r'^test/(\d+)/(?P<year>\d+)/', views.test),4.支持多个
虽然不能混用,但是用一种分组下 可以使用多个
# 无名分组支持多个  url(r'^test/(\d+)/(\d+)/', views.test),# 有名分组支持多个  url(r'^test/(?P<year1>\d+)/(?P<year2>\d+)/', views.test),

2. 常规 反向解析

假设你这个网站还未上线,经理心血来潮临时要求修改url,但是这个路径你已经在后端和前端都用了,而且成千上万个,基于这种情况如何修改?一个一个改?不如删库跑路吧!

其实很简单,我们可以使用反向解析,动态的获取到对应函数的路径

第一步:要给这个路由和视图函数对应关系起一个名字,后面直接用这个名字就可以了,具体做法如下:

url(r'^index/$',views.index,name='kkk')

第二步:根据前后端位置使用不同方法解析:

后端反向解析    后端可以在任意位置通过reverse反向解析出对应的url    from django.shortcuts import render,HttpResponse,redirect,reverse    reverse('kkk')    前端反向解析<a href="https://zhishitu.com" style="color: #800000;">"{% url 'kkk' %}">111</a>

3.分组的反向解析

#无名分组

#无名分组反向解析    url(r'^in/dex/(\d+)/$',views.index,name='kkk')        后端:        reverse('kkk',args=(1,))  # 后面的数字通常都是数据的id值    前端:        <a href="https://zhishitu.com" style="color: #800000;">"{% url 'kkk' 1 %}">按钮1</a>   # 后面的数字通常都是数据的id值

#有名分组(用法同无名分组)

#有名分组反向解析     url(r'^index/(?P<year>\d+)/$',views.index,name='kkk')        后端:        reverse('kkk',args=(1,)) # 推荐你使用上面这种  减少你的脑容量消耗        reverse('kkk',kwargs={'year':1})    前端:            <a href="https://zhishitu.com" style="color: #800000;">"{% url 'kkk' 1 %}">按钮1</a>  # 推荐你使用上面这种  减少你的脑容量消耗        <a href="https://zhishitu.com">按钮2</a>注意:在同一个应用下 别名千万不能重复!!!

#分组反向解析总结(统一格式)

总结:针对有名分组与无名分组的反向解析统一采用一种格式即可后端    reverse('kkk',args=(10,))  # 这里的数字通常都是数据的主键值前端    {% url 'kkk' 10 %}反向解析的本质:本质上就是给url和视图函数对应关系起别名,然后通过别名获取到一个能够访问对应视图函数的具体URL地址

4.反向解析应用

我们想获取前端传过来的数据可以使用反向解析了

路由:
url(r'^edit/(\d+)/',views.edit,name='edit')
前端模板语法:{
%for user_obj in user_list%} <a href="https://zhishitu.com" style="color: #800000;">'edit/{{ user_obj.pk }}/'></a> {% endfor %}视图函数from django.shortcuts import reversedef edit(request,edit_id): url = reverse('edit',args=(edit_id,))模板{% url 'edit' edit_id %}

三、路由分发

当你的django项目特别庞大的时候 路由与视图函数对应关系特别特别多
那么你的总路由urls.py代码太过冗长 不易维护

实现多人分组开发 :等多人开发完成之后 我们只需要创建一个空的django项目
然后将多人开发的app全部注册进来 在总路由实现一个路由分发,而不再做路由匹配(来了之后, 我只给你分发到对应的app中)

每一个应用都可以有自己的urls.py,static文件夹,templates文件夹(******)

django每一个app下面都可以有自己的urls.py路由层,templates文件夹,static文件夹。

  项目名下的/urls.py(总路由)不再做路由与视图函数的匹配关系,而是做路由的分发

具体做法:

#总urls中路由分发

from django.conf.urls import url,include    from app01 import urls as app01_urls  #名字重复起别名    from app02 import urls as app02_urls      url(r'^app01/',include(app01_urls))   #直接include(app01_urls) 就可以达到分发的效果    url(r'^app02/',include(app02_urls))  #总路由中 一级路由的后面千万不加$符号      

#各app中urls

from django.conf.urls import urlfrom app01 import views    urlpatterns = [        url(r'^index/',views.index)    ]

ps:同样的思想,当你的应用下的视图函数特别特别多的时候 你也可以建一个views文件夹, 里面根据功能的细分再建不同的py文件(******)

 四、名称空间

命名空间(英语:Namespace)是表示标识符的可见范围。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其它命名空间中。

由于name没有作用域,Django在反向解析URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,立即返回
我们在开发项目时,会经常使用name属性反解出URL,当不小心在不同的app的urls中定义相同的name时,可能会导致URL反解错误,为了避免这种事情发生,引入了命名空间
多个app起了相同的别名 这个时候用反向解析 并不会自动识别应用前缀如果想避免这种问题的发生,总路由分发时指定名称空间,前、后端解析的时候声明名称空间方式1:    总路由        url(r'^app01/',include('app01.urls',namespace='app01'))        url(r'^app02/',include('app02.urls',namespace='app02'))    后端解析        reverse('app01:index')        reverse('app02:index')    前端解析        {% url 'app01:index' %}        {% url 'app02:index' %}方式2:    起别名的时候不要冲突即可  一般情况下在起别名的时候通常建议以应用名作为前缀        name = 'app01_index'        name = 'app02_index'

五、伪静态

静态网页:数据是写死的 万年不变

伪静态网页的设计是为了增加百度等搜索引擎seo查询力度

url(r'^index.html',views.index,name='app01_index')

所有的搜索引擎其实都是一个巨大的爬虫程序,发现.html结尾误以为是静态网页,就会优先展示

网站优化相关 通过伪静态确实可以提高你的网站被查询出来的概率,但是再怎么优化也抵不过RMB玩家

六、虚拟环境

平时我们的python中下载了很多模块,创建项目的时候会全部加载,累的一批,那么怎样只让python只保留我们当前项目需要的模块资源呢?慢慢删除不需要的模块?累哭你

可以创建虚拟环境,我们会给每一个项目 配备该项目所需要的模块 不需要的一概不装

虚拟环境 就类似于为每个项目量身定做的解释器环境


如何创建虚拟环境:
每创建一个虚拟环境 就类似于你又下载了一个全新的python解释器(所以虚拟环境不能一直创建,消耗的都是资源啊老哥)

 七、django版本区别

1.path差别

django1.X跟django2.X版本区别    路由层1.X用的是url    而2.X用的是path        2.X中的path第一个参数不再是正则表达式,而是写什么就匹配什么 是精准匹配        当你使用2.X不习惯的时候  2.X还有一个叫re_path    2.x中的re_path就是你1.X的url        虽然2.X中path不支持正则表达式  但是它提供了五种默认的转换器    1.0版本的url和2.0版本的re_path分组出来的数据都是字符串类型    默认有五个转换器,感兴趣的自己可以去试一下    str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式    int,匹配正整数,包含0。    slug,匹配字母、数字以及横杠、下划线组成的字符串。    uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。    path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
from django.urls import path  from . import views  urlpatterns = [      path('articles/2003/', views.special_case_2003),      path('articles/<int:year>/', views.year_archive),      path('articles/<int:year>/<int:month>/', views.month_archive),      path('articles/<int:year>/<int:month>/<slug>/', views.article_detail),    # path才支持,re_path不支持  path('order/<int:year>',views.order),]  

基本规则:

以下是根据 2.0官方文档 而整理的示例分析表:(跟上面url的匹配关系)

2.自定义转换器

对于一些复杂或者复用的需要,可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:

class FourDigitYearConverter:      regex = '[0-9]{4}'      def to_python(self, value):          return int(value)      def to_url(self, value):          return '%04d' % value  

使用register_converter 将其注册到URL配置中:

from django.urls import register_converter, path  from . import converters, views  register_converter(converters.FourDigitYearConverter, 'yyyy')  urlpatterns = [      path('articles/2003/', views.special_case_2003),      path('articles/<yyyy:year>/', views.year_archive),      ...  ]  
计算机