Django路由系统
路由的作用
路由即请求地址与视图函数的映射关系,如果把网站比喻为一本书,那路由就好比是这本书的目录,在Django中路由默认配置在urls.py中,如下图:
简单的路由配置
#urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), #首页匹配 url(r'^$',views.home), url(r'test', views.test), url(r'testadd', views.testadd) ] """ url方法第一个参数是一个正则表达式 路由匹配按照正则匹配 一旦正则能够匹配到内容 会立刻执行对应的视图函数 不会再继续匹配了,所以完整的正则表达式应该是 r'^test/$' 用户输入url不加最后的斜杠 django会默认自动加上 你可以在配置文件中指定是否开启该功能 APPEND_SLASH = True #自动加斜杠,改为False就不让它自动加 """
分组
什么是分组、为何要分组呢?比如我们开发了一个博客系统,当我们需要根据文章的id查看指定文章时,浏览器在发送请求时需要向后台传递参数(文章的id号),可以使用 http://127.0.0.1:8001/article/?id=3,也可以直接将参数放到路径中http://127.0.0.1:8001/article/3/
针对后一种方式Django就需要直接从路径中取出参数,这就用到了正则表达式的分组功能了,其实分组就是给一段正则表达式加括号。分组分为两种:无名分组与有名分组
无名分组
在路由匹配的时候给某段正则表达式加了括号
匹配的时候会将括号内正则表达式匹配到的内容当做位置参数传递给对应的视图函数,有几个分组就传几个位置参数
urls.py文件
url(r'^test/([0-9]{4})/',views.test)
views.py文件
def test(request,args): #print(args) return HttpResponse('test')
有名分组
urls.py文件
# 该正则会匹配url地址的路径部分为:article/数字/ # 匹配的时候会将括号内正则表达式匹配到的内容当做关键字参数(article_id=匹配成功的数字)传递给对应的视图函数 url(r'^article/(?P<article_id>\d+)/',views.article)
views.py文件
# 需要额外增加一个形参,形参名必须为article_id def article(request,article_id): return HttpResponse('id为 %s 的文章内容...' %article_id)
补充:
# 无名有名不能混合使用 # url(r'^test/(\d+)/(?P<year>\d+)/', views.test), #错误写法 # 虽然不能混合使用 但是同一种命名方式 可以使用多个url(r'^test/(\d+)/(\d+)/',views.test), url(r'^article/(?P<xxx>\d+)/(?P<year>\d+)/',views.article),
反向解析
反向解析:给路由与视图函数的对应关系起一个名字(这个名字在整个项目中不要重复),前端和后端可以根据这个名字通过一些方法得到一个结果,这个结果可以访问名字所对应的url
在软件开发初期,url地址的路径设计可能并不完美,后期需要进行调整,如果项目中很多地方使用了该路径,一旦该路径发生变化,就意味着所有使用该路径的地方都需要进行修改,这是一个非常繁琐的操作。
解决方案就是在编写一条url时,可以通过参数name为url地址的路径部分起一个别名,项目中就可以通过别名来获取这个路径。以后无论路径如何变化别名与路径始终保持一致。
上述方案中通过别名获取路径的过程称为反向解析。
urls.py
url(r'^testadd/',views.testadd,name='add') # 路径testadd/的别名为add
html文件
{% url 'add' %}
views.py
from django.shortcuts import render,HttpResponse,redirect from django.shortcuts import reverse #reverse用于反向解析 url = reverse('add')
无名反向解析
url(r'^aritcle/(\d+)/$',views.article,name='article_page'), # 无名分组 # 针对无名分组,比如我们要反向解析出:/aritcle/1/ 这种路径,写法如下 在views.py中,反向解析的使用: url = reverse('article_page',args=(1,)) 在html文件中,反向解析的使用 {% url 'article_page' 1 %}
有名反向解析
url(r'^user/(?P<uid>\d+)/$',views.article,name='user_page'), # 有名分组 # 针对有名分组,比如我们要反向解析出:/user/1/ 这种路径,写法如下 在views.py中,反向解析的使用: url = reverse('user_page',kwargs={'uid':1}) 在html文件中,反向解析的使用 {% url 'user_page' uid=1 %}
路由分发
当django项目比较庞大时,路由与视图函数对应关系较多,总路由代码太多冗长,不便于维护管理
所以我们应该将app自己的路由交由自己管理,总路由不再做路由与视图函数的对应关系。而仅仅只做一个分发任务的操作,django支持每个app都可以有自己的urls.py。
根据请求的不同 识别出当前请求需要访问的功能属于哪个app,然后自动下发到对应app里面的urls.py中。由app里面的urls.py做路由与视图函数的匹配
不仅如此每个app除了可以有自己的urls.py之外,还可以有自己的static文件夹和templates模板文件,
基于上面的特点,django分小组开发会变得额外的简单。每个人只需要开发自己的app即可,之后只需要创建一个空的django项目,将多个人的app全部拷贝项目下,配置文件注册,总路由分发一次
1、创建两个app
2、在每个app下手动创建urls.py来存放自己的路由
app01下的urls.py文件
from django.conf.urls import url # 导入app01的views from app01 import views urlpatterns = [ url(r'^index/',views.index), ]
app01下的views.py
def index(request): return HttpResponse('我是app01的index页面...')
app02下的urls.py文件
from django.conf.urls import url # 导入app02的views from app02 import views urlpatterns = [ url(r'^index/',views.index), ]
app02下的views.py
def index(request): return HttpResponse('我是app02的index页面...')
3、在总的urls.py文件中(mysite文件夹下的urls.py)
from django.conf.urls import url,include # include就是做分发操作的 # 路由分发注意事项:应用名后面千万不能加$ # from app01 import urls as app01_urls # from app02 import urls as app02_urls # url(r'^app01/',include(app01_urls)), # url(r'^app02/',include(app02_urls)) # 简写 url(r'^app01/',include('app01.urls')), url(r'^app02/',include('app02.urls'))
名称空间
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' %}
在给路由与视图函数起别名的时候只需要保证永远不出现冲突的情况即可
通常情况下我们推荐起别名的时候加上当前应用的应用名前缀
url(r'^index/',views.index,name='app01_index') url(r'^index/',views.index,name='app02_index')
虚拟环境
针对不同的项目,我们有时为了避免加载资源时的消耗,只需要安装项目所需要的功能模块,项目用不到的一概不装,就需要用到虚拟环境
虚拟环境就类似于一个纯净的python解释器环境,每创建一个虚拟环境就类似于你重新下载一个python解释器。
Django版本区别
路由层
1.x 用的是url
2.x、3.x 用的是path
url 第一个参数是一个正则表达式
而 path 第一个参数不支持正则表达式 写什么就匹配什么
如果你觉得path不好用,2.x、3.x版本给你提供了一个跟url一样的功能
re_path 等价于1.x版本里面的url功能
#虽然path不支持正则表达式 但是它给你提供了五种默认的转换器 str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式 int,匹配正整数,包含0。 slug,匹配字母、数字以及横杠、下划线组成的字符串。 uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。 path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?) path('login/<int:year>/',login)
伪静态
url以.html结尾给人的感觉好像是这个文件是写死的,内容不会轻易的改变。这样可以提高你的网站被搜索引擎收藏的力度,提供网站的SEO查询效率。