Django
Web框架简介
- 1.首先web应用的程序的处理流程是啥样的?
简单说是这样的
digraph G{
客户 -> 服务器
服务器 -> 客户
}
具体就是这样的
[外链图片转存失败(img-CNvXHcGp-1562671121883)(2019-05-12-11-07-14.png)]
- 2.Web程序框架有啥意义?
- 用于搭建Web应用程序
- 免去不同Web应用相同代码部分的重复编写,只需关心Web应用核心的业务逻辑实现
- 3.说这些都没懂,到底Web程序框架的本质是啥?
再来看个简图
digraph G{
输入 -> 处理 -> 输出
}
这6个字就是本质
- 专业解释就是
- 1.接收并解析HTTP请求,获取具体的请求信息
- 2.处理本次HTTP请求,即完成本次请求的业务逻辑处理
- 3.构造并返回处理结果——HTTP响应
接下来就让我门看看啥是Django吧!
digraph G{
GO->Django
}
什么是Django
- Django啊就是用python实现的一个重量级web应用程序框架,当然还有另一个轻量级框架Flask(这里不介绍)
长啥样
[外链图片转存失败(img-MXhS6pkr-1562671121884)(2019-05-12-11-34-17.png)]
怎么来的呢
Django,发音为[`dʒæŋɡəʊ],是用python语言写的开源web开发框架,并遵循MVC设计。
劳伦斯出版集团为了开发以新闻内容为主的网站,而开发出来了这个框架,于2005年7月在BSD许可证下发布。
这个名称来源于比利时的爵士音乐家DjangoReinhardt,他是一个吉普赛人,主要以演奏吉它为主,
还演奏过小提琴等。
由于Django在近年来的迅速发展,应用越来越广泛,被著名IT开发杂志SDTimes评选为2013SDTimes100,
位列"API、库和框架"分类第6位,被认为是该领域的佼佼者。
django信念
Django的主要目的是简便、快速的开发数据库驱动的网站。
它强调代码复用,多个组件可以很方便的以"插件"形式服务于整个框架,Django有许多功能强大的第三方插件,
你甚至可以很方便的开发出自己的工具包。
这使得Django具有很强的可扩展性。它还强调快速开发和DRY(DoNotRepeatYourself)原则。
他有哪些特点
- 它是重量级框架,对比Flask框架,Django原生提供了众多的功能组件,让开发更简便快速。
- 提供项目工程管理的自动化脚本工具
- 数据库ORM支持(对象关系映射,英语:Object Relational Mapping)
- 模板
- 表单
- Admin管理站点
- 文件管理
- 认证权限
- session机制
- 缓存
- Django的设计思想是啥呢 —> MVC ---->啥又是MVC
设计模式听过没? 对,他就是设计模式的一种,其核心思想是分工、解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。
MVC的全拼为Model-View-Controller,最早由TrygveReenskaug在1978年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件设计模式,是为了将传统的输入(input)、处理(processing)、输出(output)任务运用到图形化用户交互模型中而设计的。随着标准输入输出设备的出现,开发人员只需要将精力集中在业务逻辑的分析与实现上。后来被推荐为Oracle旗下Sun公司Java EE平台的设计模式,并且受到越来越多的使用ColdFusion和PHP的开发者的欢迎。现在虽然不再使用原来的分工方式,但是这种分工的思想被沿用下来,广泛应用于软件工程中,是一种典型并且应用广泛的软件架构模式。后来,MVC的思想被应用在了Web开发方面,被称为Web MVC框架。
- 具体来说是啥样的呢? —>别急 —>看下图
[外链图片转存失败(img-yDXQ4BCX-1562671121884)(2019-05-12-11-50-38.png)]
M全拼为Model,主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。
V全拼为View,用于封装结果,生成页面展示的html内容。
C全拼为Controller,用于接收请求,处理业务逻辑,与Model和View交互,返回结果。
- 和Django有毛关系 —>额–>其实Django根据MVC设计了MVT
[外链图片转存失败(img-SRoKNaWE-1562671121885)(2019-05-12-13-01-57.png)]
M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数据处理。
V全拼为View,与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html。
- 换汤不换药而已
1.11版中文文档
https://yiyibooks.cn/xx/Django_1.11.6/index.html
源码
https://github.com/django/django
怎么进行工程搭建
在讨论工程环境搭建之前提一个话题
Ubuntu环境下python 不支持安装同一个第三方库的多个版本
digraph G{
已经安装了djangoV1版本 ->再安装djangoV2
再安装djangoV2 -> V1版本会被V2覆盖
}
那么问题来了—>我开发可能用到不同版本
- 你可能会说都用一个版本就是了---->问题是项目可能会在不同环境下运行---->所以同一个版本就会产生django本身上下不兼容的问题
怎么解决? ------>思路来了!
digraph G{
开发工程 -> A_project工程环境盒子
开发工程 -> B_project工程环境盒子
}
即把工程需要的环境打包----->那么Virtualenv 就是这个盒子,虚拟环境
- 好了开始干活,安装这个盒子工具
Ctrl+Alt+T打开终端命令 --安装虚拟环境
- pip install virtualenv
- 1.正式开工创建工程需要的环境(创建一个盒子)
- mkvirtualenv django_py3_1.11 -p python3
- 2.安装所需要的工具django
使用django 1.11.11版本,注意需要联网(低版本兼容性好)
- pip install django==1.11.11
- 介绍下会用到的虚拟环境和pip命令
# 虚拟环境
mkvirtualenv # 创建虚拟环境
rmvirtualenv # 删除虚拟环境
workon # 进入虚拟环境、查看所有虚拟环境
deactivate # 退出虚拟环境
# pip
pip install # 安装依赖包
pip uninstall # 卸载依赖包
pip list # 查看已安装的依赖库
- 环境已经搭建好了–>创建一个工程?—>go! go!
- 创建工程
在django中,项目工程目录可以借助django提供的命令帮助我们创建。
- 切换到你想要存放工程的目录
例如:想要在桌面的code目录中创建一个名为demo的项目工程,可执行如下命令:
- cd ~/Desktop/code
- django-admin startproject demo
执行后,会多出一个新目录名为demo,此即为新创建的工程目录。
- 注:django-admin 是可执行文件
如果虚拟环境已经创建好了,但是现在重新打开一个终端命令框,这时就需要进入虚拟环境
workon django_python3_1.11
当然用熟了以后你也可以自主选择已经创建的其他虚拟环境
这里已经在虚拟环境里了,不需要操作以上命令
- 接下来我们看看工程目录把—>如下图
[外链图片转存失败(img-jjhZXdKA-1562671121885)(2019-05-12-14-40-46.png)]
- 与项目同名的目录,此处为demo。
- settings.py 是项目的整体配置文件。
- urls.py 是项目的URL配置文件。
- wsgi.py 是项目与WSGI兼容的Web服务器入口。
- manage.py 是项目管理文件,通过它管理项目。
- 在开发阶段,为了能够快速预览到开发的效果,django提供了一个纯python编写的轻量级web服务器,仅在开发阶段使用。
可以不写IP和端口,默认IP是127.0.0.1,默认端口为8000。
- 启动后可见如下信息:
[外链图片转存失败(img-8k6OofH6-1562671121885)(2019-05-12-14-45-49.png)] - 在浏览器中输入网址“127.0.0.1:8000”便可看到效果。
[外链图片转存失败(img-MCiKFyrG-1562671121886)(2019-05-12-14-46-30.png)]
注:
- django默认工作在调式Debug模式下,如果增加、修改、删除文件,服务器会自动重启。
- 按ctrl+c停止服务器。
- 服务器已经跑起来了—>但是我们怎么提供服务----->Go!
Django项目的创建流程
- 后面的介绍都基于pycharm
- 上边的是应用程序的主框架,实现整个框架的运行---->我们干嘛?
- 添加子功能项目,就是他的一个分支–不懂?—>看图
digraph G{
主框架 -> 子App1
子App1 -> 主框架
主框架 -> 子App2
子App2 -> 主框架
主框架 -> 子App3
子App3 -> 主框架
}
在Web应用中,通常有一些业务功能模块是在不同的项目中都可以复用的,
故在开发中通常将工程项目拆分为不同的子功能模块,各功能模块间可以保持相对的独立,
在其他工程项目中需要用到某个特定功能模块时,可以将该模块代码整体复制过去,达到复用。
在Flask框架中也有类似子功能应用模块的概念,即蓝图Blueprint。
Django的视图编写是放在子应用中的。
- 那么来吧给主框架添一个功能—>Go!
- 创建
在django中,创建子应用模块目录仍然可以通过命令来操作,即:
python manage.py startapp 子应用名称
manage.py 为上述创建工程时自动生成的管理文件。
例如,在刚才创建的demo工程中,想要创建一个用户users子应用模块,可执行:
cd ~/Desktop/code/demo
python manage.py startapp users
执行后,可以看到工程目录中多出了一个名为users的子目录。
- 来看看此时的工程目录,结构嘛!—>往下看图
[外链图片转存失败(img-kG61fC3L-1562671121886)(2019-05-12-15-03-37.png)]
admin.py 文件跟网站的后台管理站点配置相关。
apps.py 文件用于配置当前子应用的相关信息。
migrations 目录用于存放数据库迁移历史文件。
models.py 文件用户保存数据库模型类。
tests.py 文件用于开发测试用例,编写单元测试。
views.py 文件用于编写Web应用视图。
- 你以为创建好主框架就认识你了?---->错!—>快去老大那里报到!
创建出来的子应用目录文件虽然被放到了工程项目目录中,但是django工程并不能立即直接使用该子应用,需要注册安装后才能使用。
在工程配置文件settings.py中,INSTALLED_APPS项保存了工程中已经注册安装的子应用,初始工程中的INSTALLED_APPS如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
- 注册安装一个子应用的方法,即是将子应用的配置信息文件apps.py中的Config类添加到INSTALLED_APPS列表中。
例如,将刚创建的users子应用添加到工程中,可在INSTALLED_APPS列表中添加’users.apps.UsersConfig’。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users.apps.UsersConfig', # <-------注册
# 'users', # 当然你也可以这样
]
- 已经向老大报道了,我可以干活了吧?---->可以----->不过别急啊!—磨刀!
活应该怎么干—>怎么做项目功能?-----本质还记得吗---->来来来,看图!
digraph G{
输入 -> 处理
处理 -> 输出
用户资源请求url -> 服务器框架url路由管理中心
服务器框架url路由管理中心 -> Apps路由管理中心
Apps路由管理中心 -> AppsViews视图中心
AppsViews视图中心 -> AppsTemplate模板中心
AppsTemplate模板中心 -> AppsViews视图中心
AppsModels数据管理中心 ->AppsViews视图中心
AppsViews视图中心 -> AppsModels数据管理中心
AppsViews视图中心 -> 返回资源给用户
DB -> AppsModels数据管理中心
AppsModels数据管理中心 -> DB
}
-
就是啥呢–>你要一个东西—>我得按照你的要求处理好并返回给你
-
上图是客户端与服务端进行交流的顺序—>但是开发应该先做ER设计(数据结构)–>路由–>最终页面展示
玩转Model
网站开发首先你得解决数据的问题吧-怎么存怎么取?
OK—存在MYSQL之类的数据库—>但是怎么解决存取的复杂性和同步性?—>ORM
- 那么什么是ORM,他是怎么解决以上问题的—>答案就是Mapping关系映射
O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思。在ORM框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据。ORM框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程。
django中内嵌了ORM框架,不需要直接面向数据库编程,而是定义模型类,通过模型类和对象完成数据表的增删改查操作。
- 怎么映射的?
digraph G{
类 -> 表
表 -> 类
属性 -> 字段
字段 -> 属性
对象 -> 数据行
数据行 -> 对象
}
-
现在来看ORM有啥作用
[外链图片转存失败(img-fzY0wf2W-1562671121886)(2019-05-12-15-55-41.png)]
[外链图片转存失败(img-Ah7TOPgm-1562671121886)(2019-05-12-15-55-54.png)] -
从上面可以看出不经解决了存取和同步的问题,也解决了数据迁移的问题,不怕你换数据库
配置数据库
- 在哪配置,怎么配置?
在settings.py中保存了数据库的连接配置信息,Django默认初始配置使用sqlite数据库。
使用MySQL数据库首先需要安装驱动程序
pip install PyMySQL
在Django的工程同名子目录的__init__.py文件中添加如下语句
from pymysql import install_as_MySQLdb
install_as_MySQLdb()
或
import pymysql
pymysql.install_as_MySQLdb()
作用是让Django的ORM能以mysqldb的方式来调用PyMySQL。
修改DATABASES配置信息
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '127.0.0.1', # 数据库主机
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': 'mysql', # 数据库用户密码
'NAME': 'django_demo' # 数据库名字
}
}
使用数据库前需要手动在MySQL中创建数据库
create database django_demo default charset=utf8;
定义模型类
- 数据库配置好了我们该干嘛了?—>对!—>进行数据表的创建—>定义models类
模型类被定义在"应用/models.py"文件中。
模型类必须继承自Model类,位于包django.db.models中。
- 接下来首先以"图书-英雄"管理为例进行演示。
定义
from django.db import models
#定义图书模型类BookInfo
class BookInfo(models.Model):
btitle = models.CharField(max_length=20, verbose_name='名称')
bpub_date = models.DateField(verbose_name='发布日期')
bread = models.IntegerField(default=0, verbose_name='阅读量')
bcomment = models.IntegerField(default=0, verbose_name='评论量')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
db_table = 'tb_books' # 指明数据库表名
verbose_name = '图书' # 在admin站点中显示的名称
verbose_name_plural = verbose_name # 显示的复数名称
def __str__(self):
"""定义每个数据对象的显示信息"""
return self.btitle
#定义英雄模型类HeroInfo
class HeroInfo(models.Model):
GENDER_CHOICES = (
(0, 'female'),
(1, 'male')
)
hname = models.CharField(max_length=20, verbose_name='名称')
hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')
hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息')
hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书') # 外键
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
db_table = 'tb_heros'
verbose_name = '英雄'
verbose_name_plural = verbose_name
def __str__(self):
return self.hname
1) 数据库表名
模型类如果未指明表名,Django默认以 小写app应用名_小写模型类名 为数据库表名。
可通过db_table 指明数据库表名。
2) 关于主键
django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后django不会再创建自动增长的主键列。
默认创建的主键列属性为id,可以使用pk代替,pk全拼为primary key。
3) 属性命名限制
不能是python的保留关键字。
不允许使用连续的下划线,这是由django的查询方式决定的。
定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性=models.字段类型(选项)
4)字段类型
类型 说明
AutoField 自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性
BooleanField 布尔字段,值为True或False
NullBooleanField 支持Null、True、False三种值
CharField 字符串,参数max_length表示最大字符个数
TextField 大文本字段,一般超过4000个字符时使用
IntegerField 整数
DecimalField 十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数
FloatField 浮点数
DateField 日期, 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
TimeField 时间,参数同DateField
DateTimeField 日期时间,参数同DateField
FileField 上传文件字段
ImageField 继承于FileField,对上传的内容进行校验,确保是有效的图片
5) 选项
选项 说明
null 如果为True,表示允许为空,默认值是False
blank 如果为True,则该字段允许为空白,默认值是False
db_column 字段的名称,如果未指定,则使用属性的名称
db_index 若值为True, 则在表中会为此字段创建索引,默认值是False
default 默认
primary_key 若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
unique 如果为True, 这个字段在表中必须有唯一值,默认值是False
related_name 在关联查询中,代替单一对象查找多对象 对象名小写_set(book.heroinfo_set.all() 的写法
auto_now_add 只在数据添加的时候,记录时间
auto_now 数据添加和更新的时候,记录时间
null是数据库范畴的概念,blank是表单验证范畴的
6) 外键
在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:
CASCADE 级联,删除主表数据时连通一起删除外键表中数据
PROTECT 保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据
SET_NULL 设置为NULL,仅在该字段null=True允许为null时可用
SET_DEFAULT 设置为默认值,仅在该字段设置了默认值时可用
SET() 设置为特定值或者调用特定方法,如
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
def get_sentinel_user():
return get_user_model().objects.get_or_create(username='deleted')[0]
class MyModel(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET(get_sentinel_user),
)
DO_NOTHING 不做任何操作,如果数据库前置指明级联性,此选项会抛出IntegrityError异常
迁移
- 数据库表定义好了—>但是第一次要手动同步到数据库(迁移)
1)生成迁移文件
python manage.py makemigrations
2)同步到数据库中
python manage.py migrate
添加测试数据
- 没有数据搞啥啊!—>来来添加一点测试数据!
insert into tb_books(btitle,bpub_date,bread,bcomment,is_delete) values
('射雕英雄传','1980-5-1',12,34,0),
('天龙八部','1986-7-24',36,40,0),
('笑傲江湖','1995-12-24',20,80,0),
('雪山飞狐','1987-11-11',58,24,0);
insert into tb_heros(hname,hgender,hbook_id,hcomment,is_delete) values
('郭靖',1,1,'降龙十八掌',0),
('黄蓉',0,1,'打狗棍法',0),
('黄药师',1,1,'弹指神通',0),
('欧阳锋',1,1,'蛤蟆功',0),
('梅超风',0,1,'九阴白骨爪',0),
('乔峰',1,2,'降龙十八掌',0),
('段誉',1,2,'六脉神剑',0),
('虚竹',1,2,'天山六阳掌',0),
('王语嫣',0,2,'神仙姐姐',0),
('令狐冲',1,3,'独孤九剑',0),
('任盈盈',0,3,'弹琴',0),
('岳不群',1,3,'华山剑法',0),
('东方不败',0,3,'葵花宝典',0),
('胡斐',1,4,'胡家刀法',0),
('苗若兰',0,4,'黄衣',0),
('程灵素',0,4,'医术',0),
('袁紫衣',0,4,'六合拳',0);
注:如果是SQL文件使用 source 命令
演示工具的使用
- 现在有个问题,比如我想测试数据怎么办?—使用shell命令—>啥是shell
Django的manage工具提供了shell命令,帮助我们配置好当前工程的运行环境(如连接好数据库等),以便可以直接在终端中执行测试python语句。
通过如下命令进入shell
python manage.py shell
导入两个模型类,以便后续使用
from booktest.models import BookInfo, HeroInfo
- 另一个问题来了—>我想查看对数据库的操作记录,怎么办?—>mysql.log日志
查看mysql数据库日志可以查看对数据库的操作记录。 mysql日志文件默认没有产生,需要做如下配置:
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
[外链图片转存失败(img-9SFiBvkA-1562671121887)(2019-05-12-16-46-59.png)]
把68,69行前面的#去除,然后保存并使用如下命令重启mysql服务。
sudo service mysql restart
使用如下命令打开mysql日志文件。
tail -f /var/log/mysql/mysql.log # 可以实时查看数据库的日志内容
# 如提示需要sudo权限,执行
# sudo tail -f /var/log/mysql/mysql.log