深入模型
在上一个章节中,我们提到了Django是基于MVC架构的Web框架,MVC架构追求的是“模型”和“视图”的解耦合。所谓“模型”说得更直白一些就是数据(的表示),所以通常也被称作“数据模型”。在实际的项目中,数据模型通常通过数据库实现持久化操作,而关系型数据库在过去和当下都是持久化的首选方案,下面我们通过完成一个投票项目来讲解和模型相关的知识点。投票项目的首页会展示某在线教育平台所有的学科;点击学科可以查看到该学科的老师及其信息;用户登录后在查看老师的页面为老师投票,可以投赞成票和反对票;未登录的用户可以通过登录页进行登录;尚未注册的用户可以通过注册页输入个人信息进行注册。在这个项目中,我们使用MySQL数据库来实现数据持久化操作。
创建项目和应用
我们首先创建Django项目vote
并为其添加虚拟环境和依赖项。接下来,在项目下创建名为polls
的应用和保存模板页的文件夹tempaltes
,项目文件夹的结构如下所示。
根据上面描述的项目需求,我们准备了四个静态页面,分别是展示学科的页面subjects.html
,显示学科老师的页面teachers.html
,登录页面login.html
,注册页面register.html
,稍后我们会将静态页修改为Django项目所需的模板页。
配置关系型数据库MySQL
-
在MySQL中创建数据库,创建用户,授权用户访问该数据库。
create database vote default charset utf8; create user 'hellokitty'@'%' identified by 'Hellokitty.618'; grant all privileges on vote.* to 'hellokitty'@'%'; flush privileges;
-
在MySQL中创建保存学科和老师信息的二维表(保存用户信息的表稍后处理)。
use vote; -- 创建学科表 create table `tb_subject` ( `no` integer auto_increment comment '学科编号', `name` varchar(50) not null comment '学科名称', `intro` varchar(1000) not null default '' comment '学科介绍', `is_hot` boolean not null default 0 comment '是不是热门学科', primary key (`no`) ); -- 创建老师表 create table `tb_teacher` ( `no` integer auto_increment comment '老师编号', `name` varchar(20) not null comment '老师姓名', `sex` boolean not null default 1 comment '老师性别', `birth` date not null comment '出生日期', `intro` varchar(1000) not null default '' comment '老师介绍', `photo` varchar(255) not null default '' comment '老师照片', `gcount` integer not null default 0 comment '好评数', `bcount` integer not null default 0 comment '差评数', `sno` integer not null comment '所属学科', primary key (`no`), foreign key (`sno`) references `tb_subject` (`no`) );
-
在虚拟环境中安装连接MySQL数据库所需的依赖项。
pip install mysqlclient
说明:如果因为某些原因无法安装
mysqlclient
三方库,可以使用它的替代品pymysql
,pymysql
是用纯Python开发的连接MySQL的Python库,安装更容易成功,但是需要在Django项目文件夹的__init__.py
中添加如下所示的代码。import pymysql pymysql.install_as_MySQLdb()
如果使用Django 2.2及以上版本,还会遇到PyMySQL跟Django框架的兼容性问题,兼容性问题会导致项目无法运行,需要按照GitHub上PyMySQL仓库Issues中提供的方法进行处理。总体来说,使用
pymysql
会比较麻烦,强烈建议大家首选安装mysqlclient
。 -
修改项目的settings.py文件,首先将我们创建的应用
polls
添加已安装的项目(INSTALLED_APPS
)中,然后配置MySQL作为持久化方案。INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'polls', ] DATABASES = { 'default': { # 数据库引擎配置 'ENGINE': 'django.db.backends.mysql', # 数据库的名字 'NAME': 'vote', # 数据库服务器的IP地址(本机可以写localhost或127.0.0.1) 'HOST': 'localhost', # 启动MySQL服务的端口号 'PORT': 3306, # 数据库用户名和口令 'USER': 'hellokitty', 'PASSWORD': 'Hellokitty.618', # 数据库使用的字符集 'CHARSET': 'utf8', # 数据库时间日期的时区设定 'TIME_ZONE': 'Asia/Chongqing', } }
在配置ENGINE属性时,常用的可选值包括:
'django.db.backends.sqlite3'
:SQLite嵌入式数据库。'django.db.backends.postgresql'
:BSD许可证下发行的开源关系型数据库产品。'django.db.backends.mysql'
:甲骨文公司经济高效的数据库产品。'django.db.backends.oracle'
:甲骨文公司关系型数据库旗舰产品。
其他的配置可以参考官方文档中数据库配置的部分。
-
Django框架提供了ORM来解决数据持久化问题,ORM翻译成中文叫“对象关系映射”。因为Python是面向对象的编程语言,我们在Python程序中使用对象模型来保存数据,而关系型数据库使用关系模型,用二维表来保存数据,这两种模型并不匹配。使用ORM是为了实现对象模型到关系模型的双向转换,这样就不用在Python代码中书写SQL语句和游标操作,因为这些都会由ORM自动完成。利用Django的ORM,我们可以直接将刚才创建的学科表和老师表变成Django中的模型类。
python manage.py inspectdb > polls/models.py
我们可以对自动生成的模型类稍作调整,代码如下所示。
from django.db import models class Subject(models.Model): no = models.AutoField(primary_key=True, v