路由系统
回顾
第一章有说到,Django通过url分发器将我们在浏览器中输入的一个个url页面请求分发给不同的view进行处理。本章主要分析下由url分发器组成的Django路由系统。(本章主要针对Django2.0之后的版本,Django2.0之前的版本可能会有所不同)
还是回到我们第一章新建的项目结构
myproject
├── manage.py #django管理主程序
├── myapp #app目录
│ ├── __init__.py
│ ├── admin.py #注册后台管理文件
│ ├── apps.py #应用配置文件
│ ├── migrations #数据迁移目录
│ │ └── __init__.py
│ ├── models.py #应用模型文件,对应MTV架构中的M
│ ├── tests.py #测试文件
│ └── views.py #视图文件,对应MTV架构中的V
└── myproject #项目配置目录
├── __init__.py
├── settings.py #项目主配置文件
├── urls.py #url路由系统文件
└── wsgi.py #网络通信接口文件
当我们新建一个项目,通过python manage.py runserver
启动后。此时在浏览器中访问127.0.0.1:8000,就可以看到Django的欢迎界面。127.0.0.0:8000相当于127.0.0.1:8000/后接空的地址,这里如果没有自定义的话,django默认将该地址绑定到了django的欢迎界面。
为了绑定URL和视图函数,Django使用了URLconf。
URLconf介绍
URLconf就像是Django所支撑网站的目录。它的本质是 URL 模式以及要为该 URL 模式调用的视图函数之间的映射表。Django以这种方式将不同的URL分发给不同的视图处理函数。
当我们创建一个项目后,Django已经自动创建了一份URLconf(即urls.py文件)。在项目目录结构中,能够找到它。让我们看看它的代码。
1 """myproject URL Configuration
2
3 The `urlpatterns` list routes URLs to views. For more information please see:
4 https://docs.djangoproject.com/en/2.0/topics/http/urls/
5 Examples:
6 Function views
7 1. Add an import: from my_app import views
8 2. Add a URL to urlpatterns: path('', views.home, name='home')
9 Class-based views
10 1. Add an import: from other_app.views import Home
11 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12 Including another URLconf
13 1. Import the include() function: from django.urls import include, path
14 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 """
16 from django.contrib import admin
17 from django.urls import path
18
19 urlpatterns = [
20 path('admin/', admin.site.urls),
21 ]
可以看出,Django在20行已经构建好了一份映射。该映射为Django自带后台url的映射。注释中介绍了常见功能。让我们按照介绍来创建我们第一个url映射。
1 """myproject URL Configuration
2
3 The `urlpatterns` list routes URLs to views. For more information please see:
4 https://docs.djangoproject.com/en/2.0/topics/http/urls/
5 Examples:
6 Function views
7 1. Add an import: from my_app import views
8 2. Add a URL to urlpatterns: path('', views.home, name='home')
9 Class-based views
10 1. Add an import: from other_app.views import Home
11 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12 Including another URLconf
13 1. Import the include() function: from django.urls import include, path
14 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 """
16 from django.contrib import admin
17 from django.urls import path
18 from myapp import views #导入视图文件
19
20 urlpatterns = [
21 path('admin/', admin.site.urls),
22 path('hello/', views.hello_view, name='hello') #将url与视图函数映射起来
23 ]
现在我们已经将url与视图函数映射了起来,但是我们的视图函数还没有创建。打开项目目录myapp下的views.py文件
1 from django.shortcuts import render
2
3 # Create your views here.
添加我们的视图函数
1 from django.shortcuts import render
2 from django.http import HttpResponse
3
4 # Create your views here.
5 def hello_view(request):
6 return HttpResponse("Hello world")
现在我们在浏览器中访问 127.0.0.1:8000/hello ,就可以看到hello world
的视图界面。
工作原理
至此,我们已经构建好了我们的第一份简单的视图。通过在浏览器里敲http://127.0.0.1:8000/hello/ 能够访问得到Hello world。那么Django又是怎么完成这整个流程的呢?
一切始于项目配置文件settings.py。当运行python manage.py runserver
时,Django会根据manage.py文件里的配置去寻找项目的配置文件。如果未自定义,这个文件应该是settings.py。关于配置文件,在第二章中有相关的说明。打开配置文件,其中:
ROOT_URLCONF = 'myproject.urls'
通过ROO_URLCONF配置来指向构建项目时生成的URLConf(即myproject下的urls.py文件)
当访问 URL /hello/ 时,Django 根据 ROOT_URLCONF 的设置装载 URLconf 。 然后按顺序逐个匹配URLconf里的URLpatterns,直到找到一个匹配的。 当找到这个匹配 的URLpatterns就调用相关联的view函数,并把 HttpRequest 对象作为第一个参数。此时,请求已经由我们的路由系统转发到了视图模块处理。视图模块处理完成之后,通过HttpResponse返回结果。关于视图模块的处理及返回,会在后文中进行相关的介绍。
总结一下:
- 浏览器进来的请求转入/hello/;
- Django通过在ROOT_URLCONF配置来决定根URLconf;
- Django在URLconf中的所有URL模式中,查找第一个匹配/hello/的条目;
- 如果找到匹配,将调用相应的视图函数;
- 视图函数返回一个HttpResponse;
- Django转换HttpResponse为一个适合的HTTP response, 以网页显示出来