提交 ef8cf2ea 编写于 作者: 骆昊的技术专栏's avatar 骆昊的技术专栏

更新了Django部分的文档

上级 583c9520
## Django 2.x实战(01) - 快速上手
Web开发的早期阶段,开发者需要手动编写每个页面,例如一个新闻门户网站,每天都要修改它的HTML页面,这样随着网站规模和体量的增大,这种方式就变得极度糟糕。为了解决这个问题,开发人员想到了用外部程序来为Web服务器生成动态内容,也就是说HTML页面以及页面中的动态内容不再通过手动编写而是通过程序自动生成。最早的时候,这项技术被称为CGI(公共网关接口),当然随着时间的推移,CGI暴露出的问题也越来越多,例如大量重复的样板代码,总体性能较为低下等,因此在呼唤新的英雄的时代,PHP、ASP、JSP这类Web应用开发技术在上世纪90年代中后期如雨后春笋般涌现。通常我们说的Web应用是指通过浏览器来访问网络资源的应用程序,因为浏览器的普及性以及易用性,Web应用使用起来方便简单,而且在应用更新时用户通常不需要做任何的处理就能使用更新后的应用,而且也不用关心用户到底用的是什么操作系统,甚至不用区分是PC端还是移动端。
Web开发的早期阶段,开发者需要手动编写每个页面,例如一个新闻门户网站,每天都要修改它的HTML页面,这样随着网站规模和体量的增大,这种方式就变得极度糟糕。为了解决这个问题,开发人员想到了用外部程序来为Web服务器生成动态内容,也就是说HTML页面以及页面中的动态内容不再通过手动编写而是通过程序自动生成。最早的时候,这项技术被称为CGI(公共网关接口),当然随着时间的推移,CGI暴露出的问题也越来越多,例如大量重复的样板代码,总体性能较为低下等,因此在时代呼唤新英雄的背景下,PHP、ASP、JSP这类Web应用开发技术在上世纪90年代中后期如雨后春笋般涌现。通常我们说的Web应用是指通过浏览器来访问网络资源的应用程序,因为浏览器的普及性以及易用性,Web应用使用起来方便简单,免除了安装和更新应用程序带来的麻烦,而且也不用关心用户到底用的是什么操作系统,甚至不用区分是PC端还是移动端。
### Web应用机制和术语
......@@ -16,7 +16,7 @@ Web开发的早期阶段,开发者需要手动编写每个页面,例如一
| **域名** | 与Web服务器地址对应的一个易于记忆的字符串名字 |
| **DNS** | 域名解析服务,可以将域名转换成对应的IP地址 |
| **IP地址** | 网络上的主机的身份标识,通过IP地址可以区分不同的主机 |
| **HTTP** | 超文本传输协议,应用层协议,万维网数据通信的基础 |
| **HTTP** | 超文本传输协议,构建在TCP之上的应用级协议,万维网数据通信的基础 |
| **反向代理** | 代理客户端向服务器发出请求,然后将服务器返回的资源返回给客户端 |
| **Web服务器** | 接受HTTP请求,然后返回HTML文件、纯文本文件、图像等资源给请求者 |
| **Nginx** | 高性能的Web服务器,也可以用作[反向代理](https://zh.wikipedia.org/wiki/%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86)[负载均衡](https://zh.wikipedia.org/wiki/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1) 和 [HTTP缓存](https://zh.wikipedia.org/wiki/HTTP%E7%BC%93%E5%AD%98) |
......@@ -52,10 +52,12 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
1. 检查Python环境:Django 1.11需要Python 2.7或Python 3.4以上的版本;Django 2.0需要Python 3.4以上的版本。
```Shell
$ python3 --version
```
```Shell
$ python3
>>> import sys
>>> sys.version
......@@ -65,6 +67,7 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
2. 创建项目文件夹并切换到该目录,例如我们要实例一个OA(办公自动化)项目。
```Shell
$ mkdir oa
$ cd oa
```
......@@ -72,6 +75,7 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
3. 创建并激活虚拟环境。
```Shell
$ python3 -m venv venv
$ source venv/bin/activate
```
......@@ -80,6 +84,7 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
4. 更新包管理工具pip。
```Shell
(venv)$ python -m pip install --upgrade pip
```
> 注意:请注意终端提示符发生的变化,前面的`(venv)`说明我们已经进入虚拟环境,而虚拟环境下的python和pip已经是Python 3的解释器和包管理工具了。
......@@ -87,23 +92,27 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
5. 安装Django。
```Shell
(venv)$ pip install django
```
或指定版本号来安装对应的Django的版本。
```Shell
(venv)$ pip install django==1.11
```
6. 检查Django的版本。
```Shell
(venv)$ python -m django --version
(venv)$ django-admin --version
```
```Shell
(venv)$ python
>>> import django
>>> django.get_version()
......@@ -117,11 +126,12 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
| 1.11 | 2.7、3.4、3.5、3.6 |
| 2.0 | 3.4、3.5、3.6 |
> 说明:在创建这篇文章时Django 2.1版本尚未正式发布,因此我们的教程使用了2.0.5版本。
> 说明:在这篇文章时Django 2.1版本尚未正式发布,因此我们的教程使用了2.0.5版本。
7. 使用`django-admin`创建项目,项目命名为oa。
```Shell
(venv)$ django-admin startproject oa .
```
......@@ -138,6 +148,7 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
8. 启动服务器运行项目。
```Shell
(venv)$ python manage.py runserver
```
......@@ -157,11 +168,13 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
9. 接下来我们进入项目目录oa并修改配置文件settings.py,Django是一个支持国际化和本地化的框架,因此刚才我们看到的默认首页也是支持国际化的,我们将默认语言修改为中文,时区设置为东八区。
```Shell
(venv)$ cd oa
(venv)$ vim settings.py
```
```Python
# 此处省略上面的内容
# 设置语言代码
......@@ -175,6 +188,7 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
10. 回到manage.py所在的目录,刷新刚才的页面。
```Shell
(venv)$ cd ..
(venv)$ python manage.py runserver
```
......@@ -186,6 +200,7 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
1. 创建名为hrs(人力资源系统)的应用(注:一个项目可以包含多个应用)。
```Shell
(venv)$ python manage.py startapp hrs
```
......@@ -202,11 +217,13 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
2. 进入应用目录修改视图文件views.py。
```Shell
(venv)$ cd hrs
(venv)$ vim views.py
```
```Python
from django.http import HttpResponse
......@@ -218,11 +235,13 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
3. 在应用目录创建一个urls.py文件并映射URL。
```Shell
(venv)$ touch urls.py
(venv)$ vim urls.py
```
```Python
from django.urls import path
from hrs import views
......@@ -236,12 +255,14 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
4. 切换到项目目录,修改该目录下的urls.py文件,对应用中设定的URL进行合并。
```Shell
(venv) $ cd ..
(venv) $ cd oa
(venv) $ vim urls.py
```
```Python
from django.contrib import admin
from django.urls import path, include
......@@ -254,6 +275,7 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
5. 启动项目并访问应用。
```Shell
(venv)$ cd ..
(venv)$ python manage.py runserver
```
......@@ -265,11 +287,13 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
6. 修改views.py生成动态内容。
```Shell
(venv)$ cd hrs
(venv)$ vim views.py
```
```Python
from django.http import HttpResponse
from io import StringIO
......@@ -308,6 +332,7 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
1. 先回到manage.py文件所在的目录创建一个templates文件夹。
```Shell
(venv)$ cd ..
(venv)$ mkdir templates
(venv)$ cd templates
......@@ -316,10 +341,12 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
2. 创建模板页index.html。
```Shell
(venv)$ touch index.html
(venv)$ vim index.html
```
```HTML
<!DOCTYPE html>
<html lang="en">
<head>
......@@ -343,12 +370,14 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
3. 回到应用目录,修改views.py文件。
```Shell
(venv)$ cd ..
(venv)$ cd hrs
(venv)$ vim views.py
```
```Python
from django.shortcuts import render
from random import randrange
......@@ -370,12 +399,14 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
4. 切换到项目目录修改settings.py文件。
```Shell
(venv)$ cd ..
(venv)$ cd oa
(venv)$ vim settings.py
```
```Python
# 此处省略上面的内容
TEMPLATES = [
......@@ -400,6 +431,7 @@ Django诞生于2003年,它是一个在真正的应用中成长起来的项目
5. 重新运行项目并查看结果。
```Shell
(venv)$ cd ..
(venv)$ python manage.py runserver
```
......
## Django 2.x实战(02) - 深入模型
在上一个章节中,我们提到了Django是一个基于MVC架构的Web框架,MVC架构要追求的是模型和视图的解耦合,而其中的模型说得更直白一些就是数据,所以通常也被称作数据模型。在实际的项目中,数据模型通常通过数据库实现持久化操作,而关系型数据库在很长一段时间都是持久化的首选方案,在我们的OA项目中,我们选择使用MySQL来实现数据持久化。
在上一个章节中,我们提到了Django是基于MVC架构的Web框架,MVC架构追求的是“模型”和“视图的解耦合。所谓“模型”说得更直白一些就是数据,所以通常也被称作“数据模型”。在实际的项目中,数据模型通常通过数据库实现持久化操作,而关系型数据库在很长一段时间都是持久化的首选方案(当然NoSQL的方案在今天普遍被认为是关系型数据库的一个很好的补充),在下面演示的项目中,我们选择使用MySQL来实现数据持久化。
### 配置关系型数据库MySQL
1. 进入oa文件夹,修改项目的settings.py文件,首先将我们之前创建的应用hrs添加已安装的项目中,然后配置MySQL作为持久化方案。
```Shell
(venv)$ cd oa
(venv)$ vim settings.py
```
```Python
# 此处省略上面的代码
INSTALLED_APPS = [
......@@ -40,10 +42,10 @@
在配置ENGINE属性时,常用的可选值包括:
- `'django.db.backends.sqlite3'`:SQLite嵌入式数据库
- `'django.db.backends.postgresql'`:BSD许可证下发行的开源关系型数据库产品
- `'django.db.backends.mysql'`:转手多次目前属于甲骨文公司的经济高效的数据库产品
- `'django.db.backends.oracle'`:甲骨文公司的旗舰关系型数据库产品
- `'django.db.backends.sqlite3'`:SQLite嵌入式数据库
- `'django.db.backends.postgresql'`:BSD许可证下发行的开源关系型数据库产品
- `'django.db.backends.mysql'`:转手多次目前属于甲骨文公司的经济高效的数据库产品
- `'django.db.backends.oracle'`:甲骨文公司的关系型数据库旗舰产品。
其他的配置可以参考官方文档中[数据库配置](https://docs.djangoproject.com/zh-hans/2.0/ref/databases/#third-party-notes)的部分。
......@@ -52,12 +54,14 @@
2. 安装MySQL客户端工具,Python 3中使用PyMySQL,Python 2中用MySQLdb。
```Shell
(venv)$ pip install pymysql
```
如果使用Python 3需要修改**项目**`__init__.py`文件并加入如下所示的代码,这段代码的作用是将PyMySQL视为MySQLdb来使用,从而避免Django找不到连接MySQL的客户端工具而询问你:“Did you install mysqlclient? ”(你安装了mysqlclient吗?)。
```Python
import pymysql
pymysql.install_as_MySQLdb()
......@@ -66,11 +70,13 @@
3. 运行manage.py并指定migrate参数实现数据库迁移,为应用程序创建对应的数据表,当然在此之前需要**先启动MySQL数据库服务器并创建名为oa的数据库**,在MySQL中创建数据库的语句如下所示。
```SQL
drop database if exists oa;
create database oa default charset utf8;
```
```Shell
(venv)$ cd ..
(venv)$ python manage.py migrate
Operations to perform:
......@@ -95,11 +101,13 @@
4. 可以看到,Django帮助我们创建了10张表,这些都是使用Django框架需要的东西,稍后我们就会用到这些表。除此之外,我们还应该为我们自己的应用创建数据模型。如果要在hrs应用中实现对部门和员工的管理,我们可以创建如下所示的数据模型。
```Shell
(venv)$ cd hrs
(venv)$ vim models.py
```
```Python
from django.db import models
......@@ -129,13 +137,13 @@
class Meta:
db_table = 'tb_emp'
```
> 说明:上面定义模型时使用了字段类及其属性,其中IntegerField对应数据库中的integer类型,CharField对应数据库的varchar类型,DecimalField对应数据库的decimal类型,ForeignKey用来建立多对一外键关联。字段属性primary_key用于设置主键,max_length用来设置字段的最大长度,db_column用来设置数据库中与字段对应的列,verbose_name则设置了Django后台管理系统中该字段显示的名称。如果对这些东西感到很困惑也不要紧,文末提供了字段类、字段属性、元数据选项等设置的相关说明,不清楚的读者可以稍后查看对应的参考指南。
5. 通过模型创建数据表。
```Shell
(venv)$ cd ..
(venv)$ python manage.py makemigrations hrs
Migrations for 'hrs':
......@@ -158,6 +166,7 @@
1. 创建超级管理员账号。
```Shell
(venv)$ python manage.py createsuperuser
Username (leave blank to use 'hao'): jackfrued
Email address: jackfrued@126.com
......@@ -169,6 +178,7 @@
2. 启动Web服务器,登录后台管理系统。
```Shell
(venv)$ python manage.py runserver
```
......@@ -185,18 +195,19 @@
3. 注册模型类。
```Shell
(venv)$ cd hrs
(venv)$ vim admin.py
```
```Python
from django.contrib import admin
from hrs.models import Emp, Dept
admin.site.register(Dept)
admin.site.register(Emp)
```
注册模型类后,就可以在后台管理系统中看到它们。
......@@ -224,6 +235,7 @@
再次修改admin.py文件,通过注册模型管理类,可以在后台管理系统中更好的管理模型。
```Python
from django.contrib import admin
from hrs.models import Emp, Dept
......@@ -243,7 +255,6 @@
admin.site.register(Dept, DeptAdmin)
admin.site.register(Emp, EmpAdmin)
```
![](./res/admin-model-depts.png)
......@@ -253,6 +264,7 @@
为了更好的查看模型数据,可以为Dept和Emp两个模型类添加`__str__`魔法方法。
```Python
from django.db import models
......@@ -294,6 +306,7 @@
在了解了Django提供的模型管理平台之后,我们来看看如何从代码层面完成对模型的CRUD(Create / Read / Update / Delete)操作。我们可以通过manage.py开启Shell交互式环境,然后使用Django内置的ORM框架对模型进行CRUD操作。
```Shell
(venv)$ cd ..
(venv)$ python manage.py shell
Python 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28)
......@@ -306,6 +319,7 @@ Type "help", "copyright", "credits" or "license" for more information.
#### 新增
```Shell
>>>
>>> from hrs.models import Dept, Emp
>>> dept = Dept(40, '研发2部', '深圳')
......@@ -315,6 +329,7 @@ Type "help", "copyright", "credits" or "license" for more information.
#### 更新
```Shell
>>>
>>> dept.name = '研发3部'
>>> dept.save()
......@@ -325,6 +340,7 @@ Type "help", "copyright", "credits" or "license" for more information.
查询所有对象。
```Shell
>>>
>>> Dept.objects.all()
<QuerySet [<Dept: 研发1部>, <Dept: 销售1部>, <Dept: 运维1部>, <Dept: 研发3部>]>
......@@ -333,6 +349,7 @@ Type "help", "copyright", "credits" or "license" for more information.
过滤数据。
```Shell
>>>
>>> Dept.objects.filter(name='研发3部') # 查询部门名称为“研发3部”的部门
<QuerySet [<Dept: 研发3部>]>
......@@ -350,6 +367,7 @@ Type "help", "copyright", "credits" or "license" for more information.
查询单个对象。
```Shell
>>>
>>> Dept.objects.get(pk=10)
<Dept: 研发1部>
......@@ -364,6 +382,7 @@ Type "help", "copyright", "credits" or "license" for more information.
排序数据。
```Shell
>>>
>>> Dept.objects.order_by('no') # 查询所有部门按部门编号升序排列
<QuerySet [<Dept: 研发1部>, <Dept: 销售1部>, <Dept: 运维1部>, <Dept: 研发3部>]>
......@@ -375,6 +394,7 @@ Type "help", "copyright", "credits" or "license" for more information.
切片数据。
```Shell
>>>
>>> Dept.objects.order_by('no')[0:2] # 按部门编号排序查询1~2部门
<QuerySet [<Dept: 研发1部>, <Dept: 销售1部>]>
......@@ -386,6 +406,7 @@ Type "help", "copyright", "credits" or "license" for more information.
高级查询。
```Shell
>>>
>>> Emp.objects.filter(dept__no=10) # 根据部门编号查询该部门的员工
<QuerySet [<Emp: 乔峰>, <Emp: 张无忌>, <Emp: 张三丰>]>
......@@ -406,6 +427,7 @@ Type "help", "copyright", "credits" or "license" for more information.
#### 删除
```Shell
>>>
>>> Dept.objects.get(pk=40).delete()
(1, {'hrs.Dept': 1})
......@@ -543,6 +565,7 @@ ManyToManyField属性
Q对象(用于执行复杂查询)的使用:
```Shell
>>>
>>> from django.db.models import Q
>>> Emp.objects.filter(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册