Django框架(二):设计模型
1. 设计模型
我们之前操作数据库是通过写sql语句,那么能不能不写sql语句就可以操作数据库呢? 当然可以,这就要使用orm框架了。
1.1 orm框架
o是object,也就类对象的意思,r是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,m是mapping,是映射的意思。在orm框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据。orm框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程。
django中内嵌了orm框架,不需要直接面向数据库编程,而是定义模型类,通过模型类和对象完成数据表的增删改查操作。
使用django进行数据库开发有三个步骤:
1.在models.py中定义模型类
2.迁移
3.通过类和对象完成数据增删改查操作
下面我们就以保存图书信息为例来给大家介绍django中进行数据库开发的整个流程。
1.2 创建模型
在booktest下的models.py中创建模型,需要继承models.model类:
from django.db import models #设计和表对应的类 模型类 # create your models here. #图书类 class bookinfo(models.model): '''图书模型类''' #图书名称 charfield说明是一个字符串 max_length指定字符串的最大长度 btitle = models.charfield(max_length=20) #出版日期 datefield说明是一个日期类型 bpub_date = models.datefield()
1.3 迁移
迁移有两步:
1.生成迁移文件:根据模型类生成创建表的迁移文件。
2.执行迁移:根据第一步生成的迁移文件在数据库中创建表。
生成迁移文件命令如下:
python manage.py makemigrations
执行生成迁移文件命令后,会在应用booktest目录下的migrations目录中生成迁移文件。
我们打开这个文件,内容如下:
# generated by django 3.0.2 on 2020-01-15 07:01 from django.db import migrations, models class migration(migrations.migration): initial = true dependencies = [ ] operations = [ migrations.createmodel( name='bookinfo', fields=[ ('id', models.autofield(auto_created=true, primary_key=true, serialize=false, verbose_name='id')), ('btitle', models.charfield(max_length=20)), ('bpub_date', models.datefield()), ], ), ]
django框架根据我们设计的模型类生成了迁移文件,在迁移文件中我们可以看到fields列表中每一个元素跟bookinfo类属性名以及属性的类型是一致的。同时我们发现多了一个id项,这一项是django框架帮我们自动生成的,在创建表的时候id就会作为对应表的主键列,并且主键列自动增长。
当执行迁移命令后,django框架会读取迁移文件自动帮我们在数据库中生成对应的表格。
django默认采用sqlite3数据库,上图中的db.sqlite3就是django框架帮我们自动生成的数据库文件。 sqlite3是一个很小的数据库,通常用在手机中,它跟mysql一样,我们也可以通过sql语句来操作它。
但是我们一般是使用mysql作为案例的,所以我们需要将模型转为mysql数据库中的表。
databases = { 'default': { 'engine': 'django.db.backends.mysql', 'name':'bms', # 要连接的数据库,连接前需要创建好 'user':'root', # 连接数据库的用户名 'password':'root', # 连接数据库的密码 'host':'127.0.0.1', # 连接主机,默认本机 'port':3306 # 端口 默认3306 } }
name即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建 user和password分别是数据库的用户名和密码。设置完后,再启动我们的django项目前,我们需要激活我们的mysql。然后,启动项目,会报错:no module named mysqldb 。这是因为django默认你导入的驱动是mysqldb,可是mysqldb对于py3有很大问题,所以我们需要的驱动是pymysql。所以我们还需要找到项目名下的__init__,在里面写入:
import pymysql pymysql.install_as_mysqldb()
然后我们还要注意一个报错,报错如下:
django.core.exceptions.improperlyconfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
mysqlclient目前只支持到python3.4,因此如果使用的更高版本的python,需要修改如下:
通过路径查找e:\pythondaima\venv\lib\site-packages\django\db\backends\mysql\base..py。在这个路径下找到如下地方:
注释掉就ok了。
还有就是上一章讲过的,确保配置文件中的installed_apps中写入我们创建的app名称。
installed_apps = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'booktest', ]
删除原来生成的文件,重新运行两条命令:
python manage.py makemigrations
python manage.py migrate
我们可以看到生成的表名叫做booktest_bookinfo,booktest是应用的名字,bookinfo是模型类的名字。
我们再弄个角色类:
在booktest/models.py,定义角色类:
class roleinfo(models.model): '''角色人物模型类''' # 角色名 rname = models.charfield(max_length=20) # 性别 rgender = models.booleanfield() # 备注 rcomment = models.charfield(max_length=100) # 关系属性 rbook = models.foreignkey('bookinfo',on_delete=models.cascade)
在外键值的后面加上 on_delete=models.cascade,因为在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,此参数为了避免两个表里的数据不一致问题,不然会报错。
这里要说明的是,bookinfo类和roleinfo类之间具有一对多的关系,这个一对多的关系应该定义在多的那个类,也就是roleinfo类中。
在我们之后迁移生成表的时候,django框架就会自动帮我们在图书表和角色表之间建立一个外键关系。
python manage.py makemigrations
python manage.py migrate
1.4 操作数据库
1.4.1 单表操作
完成数据表的迁移之后,下面就可以通过进入项目的shell,进行简单的api操作。如果需要退出项目,可以使用ctrl+d快捷键或输入quit()。
进入项目shell的命令:
python manage.py shell
首先引入booktest/models中的类:
from booktest.models import bookinfo,roleinfo
查询所有图书信息:
bookinfo.objects.all()
因为当前并没有数据,所以返回空列表。
新建图书对象:
b=bookinfo() b.btitle="斗罗大陆" from datetime import date b.bpub_date=date(2008,12,14) b.save()
再次查询所有图书信息:
bookinfo.objects.all()
查找图书信息并查看值:
b=bookinfo.objects.get(id=1) b b.id b.btitle b.bpub_date
修改图书信息:
b.bpub_date=date(2017,1,1) b.save() b.bpub_date
删除图书信息:
b.delete()
1.4.2 多表关联操作
对于roleinfo可以按照上面的方式进行增删改查操作。
创建一个bookinfo对象
b=bookinfo() b.btitle='abc' b.bpub_date=date(2017,1,1) b.save()
创建一个roleinfo对象
r=roleinfo() r.rname='a1' r.rgender=false r.rcomment='he is a boy' r.rbook=b r.save()
图书与角色是一对多的关系,django中提供了关联的操作方式。
获得关联集合:返回当前book对象的所有role。
b.roleinfo_set.all()
推荐阅读
-
Python Django框架实现商城项目源码加设计文档和注释
-
Flask和Django框架中自定义模型类的表名、父类相关问题分析
-
Python及Django框架生成二维码的方法分析
-
Laravel框架学习笔记(二)项目实战之模型(Models)
-
django入门二(模型)
-
Python django框架笔记(二):创建应用和django 管理
-
06.Django基础五之django模型层(二)多表操作
-
thinkphp 3.2框架视图模型 实例视图查询结果的二维数组合并操作示例
-
《柒柒架构》DDD领域驱动设计--领域模型(二)
-
python web学习笔记二---Django框架应用和基本运行方式(基础的用户登录)