一.ORM
1.ORM简介:
ORM,全拼Object- Relation Mapping,幅意为对象关系映射,是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射ORM系统-般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。面向对象是从软件I程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象对象关系映射技术应运而生。O/R中字母0起源于“对象" (Object),而R则来自于"关系'(Relational)。 几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。目前流行的ORM产品如Java的Hibernate, .Net的EntityFormerWork等。
二.详解模型类
1.准备工作
在我们讲解模型类之前先把讲解例子的环境弄好~
1.用Pycharm自带的Django环境创建一个文件
(具体操作在web应用框架的第一天最后一部分有进行详细讲解~)
创建
然后点击 New window
=创建完成
2.替换数据库(修改为MySQL数据库)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test2', #数据库名字,
'USER': 'root', #数据库登录用户名
'PASSWORD': 'root', #数据库登录密码
'HOST': 'localhost', #数据库所在主机
'PORT': '3306', #数据库端口
}
}
数据库
3.配置init.py文件
import pymysql
pymysql.install_as_MySQLdb()
添加
4.打开终端进行操作
-
在左下角打开Terminal
打开终端操作 -
开启MySQL服务(也就是phtStudy)
开启 -
新建一个test2数据库
数据库
别忘了将上面替换数据库的名称改成test2
-
开启服务
python manage.py runserver (按Tab键自动补齐)
开启服务
然后ctrl+c退出
-
创建应用
python manage.py startapp booktest
创建app,刷新 -
注册app
注册 -
添加模型类
from django.db import models
# Create your models here.
#定义图书模型类BookInfo
class BookInfo(models.Model):
btitle = models.CharField(max_length=20)#图书名称
bpub_date = models.DateField()#发布日期
bread = models.IntegerField(default=0)#阅读量
bcomment = models.IntegerField(default=0)#评论量
isDelete = models.BooleanField(default=False)#逻辑删除
#定义英雄模型类HeroInfo
class HeroInfo(models.Model):
hname = models.CharField(max_length=20)#英雄姓名
hgender = models.BooleanField(default=True)#英雄性别
isDelete = models.BooleanField(default=False)#逻辑删除
hcomment = models.CharField(max_length=200)#英雄描述信息
hbook = models.ForeignKey('BookInfo')#英雄与图书表的关系为一对多,所以属性定义在英雄模型类中
模型类
2..定义属性
Django根据属性的类型确定以下信息:
1.当前选择的数据库支持字段的类型
2.渲染管理表单时使用的默认html控件
3.在管理站点最低限度的验证
django会为表创建自动增长的主键列,每个模型只能有一个主键列, 如果使用选项设謀属性为主键列后django不会再创建自动增长的主键列。
右击表/创建表
创建表
-
用命令行打开
show databases;
use test1;
show tables;
desc booktest_bookinfo;;
命令行打开
主键
默认创建的主键列属性为id,可以使用pk代替 , pk全拼为primary key。
- ps:pk是主键的别名,若主键名为id2,那么pk是id2的别名。
属性命名限制:
1.不能是python的保留关键字。
2.不允许使用连续的下划线,这是由django的查询方式决定的,以后会详细讲解查询。
3.定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性=models.字段类型(选项)
想了解更多有关Django的问题可以进入下面这个网址:
https://docs.djangoproject.com/en/3.0/
3.字段类型
使用时需要引入django.db.models包,段类型如下:
1.AutoField: 自动增长的IntegerField, 通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性。
2.BooleanField: 布尔字段,值为True或False。
3.NullBooleanField: 支持Null、 True、 False三种值。
4.CharField(max length=字符长度): 字符串。参数max_ length表示最大字符个数。
5.TextField: 大文本字段,一般超过4000个字符时使用。
6.IntegerField: 整数。
7.DecimalField(max_digits=None, decimal places=None): 十进制浮点数。参数max_ digits表示总位数。参数decimal places表示小数位数。
8.FloatField: 浮点数。
9.DateField[auto now= False, auto_ now_ add=Falsel]):日期。
- 参数auto_ now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false。
- 参数auto_ now_ add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false。
-
参数auto_ now_ add和auto_ now是相互排斥的,组合将会发生错误。
例子
10.TimeField:时间,参数同DateField.
11.DateTimeField:日期时间,参数同DateField。
12.FileField:.上传文件字段。
13.ImageField:继承于FileField, 对上传的内容进行校验,确保是有效的图片
4.选项
通过选项实现对字段的约束,选项如下:
1.null: 如果为True,表示允许为空,默认值是False。
2.blank: 如果为True,则该字段允许为空白,默认值是False。
3.对比: null是数据库范畴的概念,blank是表单验证范畴的。
4.db_ column: 段的名称,如果未指定,则使用属性的名称。
5.db_ index: 若为True,则在表中会为此字段创建索引,默认值是False。
6.default: 默认值。
7.primary__key: 若为True,则该字段会成为模型的主键字段,默认值是False, -般作为AutoField的选项使用。
8.unique: 如果为True,这个字段在表中必须有唯一值,默认值是False。
综合例子:
1.修改booktest/models.py中的模型类,代码如下:
from django.db import models
# Create your models here.
#定义图书模型类BookInfo
class BookInfo(models.Model):
#通过db_cloumn指定btitle对应表格中字段的名字为title
btitle = models.CharField(max_length=20,db_column='title')#图书名称
#会自动保存为当前修改的日期
bpub_date = models.DateField(auto_now=True)#发布日期
#第一次呗创建时的时间
#bpub_date = models.DateField(auto_now_add=True) # 发布日期
bread = models.IntegerField(default=0)#阅读量
bcomment = models.IntegerField(default=0)#评论量
isDelete = models.BooleanField(default=False)#逻辑删除
#定义英雄模型类HeroInfo
class HeroInfo(models.Model):
hname = models.CharField(max_length=20)#英雄姓名
hgender = models.BooleanField(default=True)#英雄性别
isDelete = models.BooleanField(default=False)#逻辑删除
#hcomment对应的数据库中的字段是可以为空的,但是通过后台管理添加的时候不能为空
hcomment = models.CharField(max_length=200,null=True,blank=False)#英雄描述信息
hbook = models.ForeignKey('BookInfo')#英雄与图书表的关系为一对多,所以属性定义在英雄模型类中
修改的两处地方
2.进行数据库迁移
- python manage.py makemigrations
-
python manage.py migrate
迁移
刷新
5.条件字段查询
实现sql中where的功能,调用过滤器filter()、 exclude()、 get(), 下面以filter()为例。
通过"属性名_id"表示外键对应对象的id值。
语法如下:
- ps:属性名称和此较运算符间使用两个下划线,所以属性名不能包括多个下划线。
属性名称__比较运算符=值
6.配置mysql的数据库日志
查看mysq数据库日志可以查看对数据库的操作记录。mysq旧志文件默认没有产生, 要做如下配置:
1.右击test2数据库点击命令行界面:
-
show variables like "general_log%"; (查找日志文件是否打开)
命令
2.如果general_log的Value为OFF,则需要输入命令:
-
SET GLOBAL general_log = 'ON';
将其打开
3.再次输入命令查看是否打开
-
show variables like "general_log%";
开啦
4.复制下面的文件夹位置:
F:\phpstudy\phpstudy_pro\Extensions\MySQL5.7.26\data
打开
打开
当你再一次执行查看文件日志的命令时,日志也会跟着增加:
例子
5.插入数据:
insert into booktest_heroinfo(hname,hgender,hbook_id,hcomment,isDelete) 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);
英雄数据
insert into booktest_bookinfo(title,bpub_date,bread,bcomment,isDelete) 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);
记得修改数据
MySql数据库回顾:
登录mysql数据库:mysql -uroot -p
查看有哪些数据库:show databases
创建数据库:create database test2 charset=utf8; #切记: 指定编码
使用数据库: use test2;
查看数据库中的表: show tables;
7.条件运算符
1.进入命令行界面:
-
python manage.py shell
shell界面
2.显示所有:
- from booktest.models import *(导入类)
-
BookInfo.objects.all()
显示所有
3.查询
-
exact:表示判等
例如:查询编号为1的图书:
报错
当报这个错误的时候,就说明保护机制起作用了,因为长时间没有操作它,所以退出重进就好了
- BookInfo.objects.filter(id=1)
-
BookInfo.objects.filter(id__exact=1)
查询
日志生成
4.模糊查询
-
contain:
说明:如果要包含%无需转义,直接写即可。
例如:查询书名包含‘英雄’的图书。
查询
日志显示 - startswith,endswith:以指定值开头或结尾
例如:查询书名以‘部’结尾的图书 -
BookInfo.objects.filter(btitle__endswith='部');
查询
以上运算符都区分大写,在这些运算符前加上i表示不区分大写,如iexact、 icontains、
istartswith、iendswith.
5.空查询
- isnull:是否为null
例如:查询书名不为空的图书 -
BookInfo.objects.filter(btitle__isnull=False);
6.范围查询
- in:是否包含在范围内
例如:查询编号为1或3或5的图书 -
BookInfo.objects.filter(id__in=[1,3,5]);
7.比较查询
- gt:大于
- gte:大于等于
- lt:小于
- lte:小于等于
例如:查询编号大于3的图书 -
BookInfo.objects.filter(id__gt=3);
不等于的运算符,使用exclude()过滤器
例如:查询编号不等于3的图书 -
BookInfo.objects.exclude(id=3);
8.日期查询
year,month、day、week_ day,hour,minute、second:对日期时间类型的属性进行运算。
例如:查询1980年发表的图书:
-
BookInfo.objects.filter(bpub_date__year=1980);
例如:查询1980年1月1日后发表的图书:
- from datetime import date
-
BookInfo.objects.filter(bpub_date__gt=date(1990,1,1));
8.F对象
之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢?
答:使用F对象,被定义在django.db.models中。
F(属性名)
例如:查询阅读量大于等于评论量的图书。
- from django.db.models import F
-
BookInfo.objects.filter(bread__gte=F('bcomment'))
可以在F对象上使用算数运算
例如:查询阅读量大于2倍评论量的图书 -
BookInfo.objects.filter(bread__gt=F('bcomment')*2)
9.Q对象
多个过滤器逐个调用表示逻辑与关系,同sq|语句中where部分的and关键字。
例:查询阅读量大于20,粗编号于3的图书。
- BookInfo.objects.filter(bread__gt=20,id__lt=3)
或者 -
BookInfo.objects.filter(bread__gt=20).filter(id__lt=3)
如果要实现逻辑或or的查询,要使用Q()对象结合|运算符, Q对象被义在django.db.models中。
Q(属性名__运算符=值)
例如:查询阅读量大于20的图书,改为Q对象如下:
- from django.db.models import Q
-
BookInfo.objects.filter(Q(bread__gt=20))
Q对象可以使用&,|,链接,&表示逻辑与,|表示逻辑或
例如:查询阅读量大于20,或者编号小于3的图书,只能使用Q对象实现
-
BookInfo.objects.filter(Q(bread__gt=20)|Q(pk__lt=3))
Q对象前可以使用~操作符,表示非not
例如:查询编号不等于3的图书:
-
BookInfo.objects.filter(~Q(pk=3))
10.聚合函数
使用aggregate()过滤器调用聚合函数。
聚合函数包括: Avg, Count, Max, Min, Sum,被定义在django.db.models中。
例:查询图书的总阅读量:
- from django.db.models import Sum
-
BookInfo.objects.aggregate(Sum('bread'))
- 注意aggregate的返回值是一个字典类型,格式如下:
{'聚合类小写__属性名‘:值}
如:{’sum__bread':3}
使用count时一般不使用aggregate()过滤器
例如:查询图书总数
-
BookInfo.objects.count()
注意count函数的返回值是一个数字。
(此文章仅作为个人学习笔记使用,如有错误欢迎指正~)
网友评论