路由即请求地址与视图函数的映射关系,若是把网站比喻为一本书,那路由就比如是这本书的目录,在Django中路由默认配置在urls.py中,以下图:html
#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就须要直接从路径中取出参数,这就用到了正则表达式的分组功能了,其实分组就是给一段正则表达式加括号。分组分为两种:无名分组与有名分组python
在路由匹配的时候给某段正则表达式加了括号
匹配的时候会将括号内正则表达式匹配到的内容当作位置参数传递给对应的视图函数,有几个分组就传几个位置参数正则表达式
urls.py文件django
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文件app
# 须要额外增长一个形参,形参名必须为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所有拷贝项目下,配置文件注册,总路由分发一次
一、建立两个app
二、在每一个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页面...')
三、在总的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解释器。
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) #除了默认的五种转换器以外 还支持你自定义转换器 class MonthConverter: regex='\d{2}' # 属性名必须为regex def to_python(self, value): return int(value) def to_url(self, value): return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
url以.html结尾给人的感受好像是这个文件是写死的,内容不会轻易的改变。这样能够提升你的网站被搜索引擎收藏的力度,提供网站的SEO查询效率。