Django 视图与链接路由

创建新项目

使用之前已经安装的 Django 1.8.13 建立一个新的 Django 项目,并命名为 dj4。

1
$ django-admin.py startproject dj4

运行后成功的话,可以看到如下的目录结构:

1
2
3
4
5
6
7
.
├── dj4
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py

我们会发现,在新建的 dj4 目录中,其中还有一个 dj4 目录,这个子目录是 dj4 中的一些项目配置 settings.py 文件、总的链接路由 urls.py 以及部署服务器时用到的 wsgi.py 文件,init.py 是 Python 包的目录结构基础文件,与包的调用有关。

在当前的 dj4 目录下,新建一个应用,并命名为 learn。

1
$ python3 manage.py startapp learn

成功后观察一下新创建的 learn 目录结构。

1
2
3
4
5
6
7
8
.
├── admin.py
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py

migrations 目录用于记录数据库变化日志。这个目录是在 Django 1.8.x 以上的版本才会存在。而在 Django 1.9.x 以上的版本,在当前目录下还会多出一个 apps.py 的文件。由于实验楼所使用的 Django 版本是 1.8.x ,所以我们无需关注它。

然后将新定义的 app 添加到 settings.py 中的 INSTALL_APPS 中(作者的 project 是建立在系统用户根目录下的,下面文件路径请读者自行修改):

1
2
3
4
5
6
7
8
9
10
11
$ vim ~/dj4/dj4/settings.py
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'learn',
)

希望大家不仅会改,还要理解此步骤的操作含义。我们将新建的 learn 这个 app 添加至 INSTALL_APPS 中,Django 就可以自动的找到 app 中的模板文件(app-name/templates/all_files)。

定义视图函数

在 learn 目录中,我们来编辑 views.py:

1
2
3
4
5
6
7
#coding: utf-8
from django.shortcuts import render
from django.http import HttpResponse


def index(request):
return HttpResponse(u"Hello Shiyanlou!")

第一行代码是为了声明文本编码为 utf-8,因为我们在代码中使用了中文。

第三行引入 HttpResponse ,它是用来向网页返回内容的,就像 Python 中的 print 函数一样,只不过 HttpResponse 是把内容显示到网页上。(其实是对数据的一个传递,这里为了简单理解,我们可以当做一个输出函数来看待。)

最后我们定义了一个 index() 函数,第一个参数必须是 request,这个与请求有关,request 变量里包含了 get 或 post 方式(这是一种 RESTful API 的设计风格,在资源传递方式中还有 put、delete 另两种方式,只是之前提到的两个最常用)传递而来的参数。我们可以对这些参数做出定制处理,然后向用户层返回待展示的数据。这里不做复杂的功能,我们直接返回 Hello Shiyanlou! 这个字符串即可。

定义视图相关的 URL,即路由配置

接下来,我们进行路由配置。编辑 urls.py 这个文件:

1
2
3
4
5
6
7
8
9
$ vim ~/dj4/dj4/urls.py
from django.conf.urls import url
from django.contrib import admin
from learn import views as learn_views # new

urlpatterns = [
url(r'^$', learn_views.index), # new
url(r'^admin/', admin.site.urls),
]

之后我们可以在项目目录中启动 Django 服务器,来查看一下效果。后面的端口号可以在合理范围内自由设置,这里以笔者的生日 1103 为例。看到如下图结果,说明成功:

1
python3 manage.py runserver 0.0.0.0:1103

进阶实验

觉得上面的实验太简单,还是在重复 Hello World ?下面笔者将带大家做一个较难的示例:用链接进行加减法的运算。

采用 GET 方法进行参数传递

在 dj4 项目中,我们继续增加一个 app,命名为 calc。

1
$ python3 manage.py startapp calc

接着,我们修改一下 calc/views.py 文件:

1
2
3
4
5
6
7
8
9
vim calc/views.py
from django.shortcuts import render
from django.http import HttpResponse

def add(request):
a = request.GET.get('a', 0)
b = request.GET.get('b', 0)
c = int(a) + int(b)
return HttpResponse(str(c))

这段代码中的意思就是 a 和 b 两个变量通过 get 方法获取参数。如果没有获取到,就默认赋值为 0。

接着继续修改 urls.py 文件,来设置路由:

1
2
3
4
5
6
7
8
9
10
11
12
$ vim dj4/urls.py
from django.conf.urls import url
from django.contrib import admin
from learn import views as learn_views
from calc import views as calc_views


urlpatterns = [
url(r'^add/$', calc_views.add, name='add'), # 注意修改了这一行
# url(r'$', learn_views.index), # 这一行先删掉,因为 $ 会造成匹配混乱
url(r'^admin/', admin.site.urls),
]

返回项目主目录,迫不及待的去测试一下:

1
$ python3 manage.py runserver 0.0.0.0:1103

当我们访问 http://0.0.0.0:1103/add/?a=3&b=2 的时候,会看到以下结果,实验成果:

巧用路由正则匹配实现加法

在 5.1 中的加法操作在我们的 Django 服务端中是这么的一个流程实现:当我们键入指定的网址时,我们通过 get 的写法在 URL 上进行明文数据传输。当 Django 通过 urls.py 匹配到指定的 URL 时,会调用 calc app 中 views.py 中的 add 方法。add 使用 get 获取参数的写法获取到 a 和 b 两个参数,并在反馈给用户渲染页面之前完成计算一起返回到用户端,并以文本的方式加以渲染浏览器显示的页面。

然而,由于路由部分使用的是正则匹配原理,我们则可以通过我们想要的方式,将数据匹配出来并随着 request 参数一起传到 views.py 亦可。此处,假如我们想使用 /add/3/2/ 这种格式,完成 3 + 2 的运算,我们来重新编辑一下 views.py,增加一个新方法 add2:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ vim calc/views.py
from django.shortcuts import render
from django.http import HttpResponse

def add(request):
a = request.GET.get('a', 0)
b = request.GET.get('b', 0)
c = int(a) + int(b)
return HttpResponse(str(c))

def add2(request, a, b):
c = int(a) + int(b)
return HttpResponse(str(c))

此时我们便需要在 urls.py 中为我们的新方法传递 a 和 b 两个变量,编辑 urls.py 文件:

1
2
3
4
5
6
7
8
9
10
11
12
$ vim dj4/urls.py
from django.conf.urls import include, url
from django.contrib import admin
from learn import views as learn_views
from calc import views as calc_views

urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
# url(r'$', learn_views.index),
# url(r'^add/', calc_views.add, name = 'add'), # 为了防止匹配问题,我们将之前的 add 方法也注释掉
url(r'^add/(\d+)/(\d+)/$', calc_views.add2, name = 'add2'),
]

测试一下,当我们以 /add/3/2/ 此种格式来输入参数,发现可以正常进行加法运算: