首先我们先了解一些ORM框架,这对后面的学习和理解很有帮助
ORM框架
O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思。在ORM框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据。ORM框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程。
django中内嵌了ORM框架,不需要直接面向数据库编程,而是定义模型类,通过模型类和对象完成数据表的增删改查操作。
使用django进行数据库开发的步骤如下:
- 配置数据库连接信息
- 在models.py中定义模型类
- 迁移
- 通过类和对象完成数据增删改查操作
首先定义书的模型类BookInfo和人物的模型类HeroInfo:
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
其次添加一些测试数据:
- 书本模型类:
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);
数据库的增加操作
一、save()方法
使用类模型进行定义后,调用.save()函数保存
1、给书模型类增加一本书
book=BookInfo(btitle='西游记',bpub_date='1988-01-01',bread='10000',bcomment='400')
book.save()
2、给人物模型类增加一个人物
hero=HeroInfo(hname='孙悟空',hgender='1',hcomment='金箍棒',hbook=book)
hero.save()
二、ctreate方法
通过模型类.objects.create()保存
给人物模型类增加一个人物
HeroInfo.objects.create(hname='沙悟净',hgender='1',hcomment='大铁铲',hbook=book)
数据库的删除操作
一、模型类对象delete方法
hero=HeroInfo.objects.get(id=19)
hero.delete()
二、模型类.objects.filter().delete()方法
HeroInfo.objects.filter(id=18).delete()
数据库的修改
一、使用HeroInfo.objects.filter().update()
HeroInfo.objects.filter(hcomment='大铁铲').update(hcomment='降妖宝杖')
二、使用hero=HeroInfo.objects.get(),hero.save()
hero=HeroInfo.objects.get(hname='沙悟净')
hero.hname='沙僧'
hero.save()
查询
一、基本查询
get 查询单一结果,如果不存在会抛出模型类.DoesNotExist异常。
HeroInfo.objects.get(hcomment='降妖宝杖')
<HeroInfo: 沙僧>
BookInfo.objects.get(id=3)
<BookInfo: 笑傲江湖>
all 查询多个结果,返回的是一个结果集(QuerySet)。
>>>BookInfo.objects.all()
>>><QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 笑傲江湖>, <BookInfo: 雪山飞狐>, <BookInfo: 西游记>]>
count 查询结果数量。
>>>HeroInfo.objects.count()
>>>19
二、过滤查询
- filter 过滤出多个结果
- exclude 排除掉符合条件剩下的结果
- get 过滤单一结果
过滤条件的表达式如下:
属性名称__比较运算符=值
# 属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线
1)判等查询—exact
例如:查询id=10的英雄
HeroInfo.objects.filter(id__exact=10)
<QuerySet [<HeroInfo: 令狐冲>]>
2)模糊查询—contains、endswith、startswith
例如:查询包含"传"的书名
BookInfo.objects.filter(btitle__contains='传')
<QuerySet [<BookInfo: 射雕英雄传>]>
例如:查询以"天"开头的书名
BookInfo.objects.filter(btitle__startswith='天')
<QuerySet [<BookInfo: 天龙八部>]>
例如:查询以"狐"结尾的书名
BookInfo.objects.filter(btitle__endswith='狐')
<QuerySet [<BookInfo: 雪山飞狐>]>
3)空查询
例如:查询书名不为空的书名
BookInfo.objects.filter(btitle__isnull=False)
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 笑傲江湖>, <BookInfo: 雪山飞狐>, <BookInfo: 西游记>]>
4)比较查询
- gt 大于 (greater then)
- gte 大于等于 (greater then equal)
- lt 小于 (less then)
- lte 小于等于 (less then equal)
例如:查询id>2书名
BookInfo.objects.filter(id__gt=2)
<QuerySet [<BookInfo: 笑傲江湖>, <BookInfo: 雪山飞狐>, <BookInfo: 西游记>]>
例如:查询id<2的书名
BookInfo.objects.filter(id__lt=2)
<QuerySet [<BookInfo: 射雕英雄传>]>
例如:查询id<=2的书名
BookInfo.objects.filter(id__lte=2)
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>]>
例如:查询id不等于3的书名
BookInfo.objects.exclude(id=3)
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 雪山飞狐>, <BookInfo: 西游记>]>
F和Q查询
1、两个字段进行对比 使用F对象
使用前先进行导包
from django.db.models.expressions import F
例如:查询阅读量大于评论量的书
BookInfo.objects.filter(bread_gte=F('bcomment'))
2、两个条件进行判断 使用Q对象
使用前先进行导包
from django.db.models.expressions import Q
& 逻辑与
例如:查询阅读量大于20并且id小于3的书
BookInfo.objects.filter(Q(bread__gt=20) & Q(id__lt=3))
# 或者
BookInfo.objects.filter(Q(bread__gt=20),Q(id__lt=3))
| 逻辑或
例如:查询阅读量大于20或id小于3的书
BookInfo.objects.filter(Q(read__gt=20) | Q(id__lt=3))
聚合查询
使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg 平均,Count 数量,Max 最大,Min 最小,Sum 求和,被定义在django.db.models中
使用前先导入函数包
from django.db.monels import Sum
例如:查询图书的总阅读量
BookInfo.objects.aggregate(Sum('bread'))
排序
使用order_by对结果进行排序,默认为升序,降序使用 “-”
升序操作
BookInfo.objects.all().order_by('bread')
降序操作
BookInfo.objects.all().order_by('-bread')
关联查询
一、一对多查询
一对多的模型类对象.多对应的模型类名小写_set
例:
# 查询ID=3的书的所有人物
book=BookInfo.objects.get(id=3)
book.heroinfo_set.all()
二、多对一查询
多对应的模型类对象.多对应的模型类中的关系类属性名
例:
# 查询ID=10的人物属于哪一本书?
hero = HeroInfo.objects.get(id=10)
hero.hbook
关联过滤查询
注意:如果没有"__运算符"部分,表示等于
1、由多模型类条件查询一模型类数据:
语法如下:
关联模型类名小写__属性名__条件运算符=值
例如:查询图书,里面包含“孙悟空”的英雄人物
BookInfo.objects.filter(heroinfo__hname='孙悟空')
2、由一模型类条件查询多模型类数据:
语法如下:
一模型类关联属性名__一模型类属性名__条件运算符=值
例如:查询书名为”天龙八部“的所有英雄
HeroInfo.objects.filter(hbook__btitle='天龙八部')
等价于:
HeroInfo.objects.filter(hbook=2)
希望通过以上简单示例数据将Django操作数据库的方法,大家可以共同学习,交流