路由的作用
路由即请求地址与视图函数的映射关系, 如果把网站比喻为一本书, 那路由就好比是这本书的目录, 在 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')
路由分发
当 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) # 除了默认的五种转换器之外 还支持你自定义转换器 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 查询效率.
来源: https://www.cnblogs.com/baohanblog/p/12158371.html