Django入门教程(十三)数据库相关操作(增删改查、属性与常量、属性与属性、聚合)
这里专门来讲一下数据库接口相关的接口(QuerySet),
1、添加数据
添加一条数据的方法有以下几种:
①Person.objects.create(name=name,age=age) ②p = Person(name="WZ", age=23) p.save() ③p = Person() name='张三' p.age = 23 p.save() ④在创建新的数据之前,先查询数据库中是否已经存在对应的数据,如果已经存在就不再创建这个对象了。适合用户注册时,判断是否已经存在这个用户名。 Person.objects.get_or_create(name="WZT", age=23) # 返回的是一个元组,(object, True/False),创建时返回 True, 已经存在时返回 False
2、查询数据.从数据库中查询出来的结果一般是一个集合,这个集合叫做 QuerySet。
(1)、所有数据的查询
①Person.objects.all() #返回值是一个结果集QuerySet. ②Person.objects.all()[:10] #切片操作,获取10个人,不支持负索引,切片可以节约内存
(2)、单条数据的查询get(), 参数就是查询条件,可以是类中的属性。
Person.objects.get(name=name)
(3)、多条数据的查询filter(),参数就是查询条件,查询结果是一个结果集QuerySet.
# first()取结果集中第一个,last()取最后一个 Person.objects.filter(user_height=179).first() Person.objects.filter(name__contains="abc") # 名称中包含 "abc"的人
3、更新数据
(1)、批量更新。适用于 .all() .filter() 等后面。 危险操作,正式场合操作务必谨慎。
Person.objects.filter(name__contains="abc").update(name='xxx') # 名称中包含 "abc"的人 都改成 xxx Person.objects.all().delete() # 删除所有 Person 记录
(2)、单个object更新。适合于 get(),get_or_create(), update_or_create() 等得到的 obj,和添加数据很类似。
p = Person.objects.get(name="张三") p.name="李四" p.email="1@qq.com" p.save() # 最后不要忘了保存!!!
4、删除数据
(1)、删除一条记录
Person.objects.get(id=1).delete() # 删除id等于1的这个人
(2)、删除多条记录
Person.objects.filter(name__contains="abc").delete() # 删除 名称中包含 "abc"的人 如果写成 people = Person.objects.filter(name__contains="abc") people.delete()效果也是一样的,
(3)、清空数据
Person.objects.all().delete() #谨慎使用
5、补充
- filter 过滤出多个结果
- exclude 排除掉符合条件剩下的结果
- get 过滤单一结果
(1)、QuerySet 是可迭代的。
persons= Person.objects.all() for person in persons: print(person.name)
(2)、 QuerySet支持查询结果排序
Person.objects.all().order_by('name') Person.objects.all().order_by('-name') # 在 name 前加一个负号,可以实现倒序
(3)、QuerySet 支持链式查询
Person.objects.filter(name__contains="张").filter(email="1@qq.com") #查询name包含张的且email是1@qq.com的 Person.objects.filter(name__contains="abc").exclude(age=23) # 找出名称含有abc, 但是排除年龄是23岁的
(4)、QuerySet 不支持负索引,但可以通过reverse()和order_by()解决
Person.objects.all()[:10] 切片操作,前10条 Person.objects.all()[-10:] 会报错!!! # 1. 使用 reverse() 解决 Person.objects.all().reverse()[:2] # 最后两条 Person.objects.all().reverse()[0] # 最后一条 # 2. 使用 order_by,在栏目(字段)前加一个负号 Person.objects.order_by('-id')[:20] # id最大的20条
(5)、查询数量
用 len() 可以得到的数量,但是推荐用count()来查询数量
len(Person.objects.all()) persons= Person.objects.all().count()
(6)、范围查询
in:是否包含在范围内。
Person.objects.filter(id__in=[1, 3, 5])
(7)、空查询
isnull:是否为null。
例:查询姓名不为空的人。
Person.objects.filter(name__isnull=False)
(8)、模糊查询
①contains:是否包含。
例:查询书名包含’传’的图书。
Person.objects.filter(name__contains='张')
②startswith、endswith:以指定值开头或结尾。
Person.objects.filter(name__startswith='李')
(9)、相等
exact:表示判等。
例:查询编号为1的人。
Person.objects.filter(id__exact=1) 可简写为: Person.objects.filter(id=1)
(10)、比较查询
- gt 大于 (greater then)
- gte 大于等于 (greater then equal)
- lt 小于 (less then)
- lte 小于等于 (less then equal)
例:查询编号大于3的人
Person.objects.filter(id__gt=3)
(11)、日期查询
year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。
例:查询1980年出生的人。
Person.objects.filter(birth_date__year=1980)
例:查询1980年1月1日后出生的人。
Person.objects.filter(birth_date__gt=date(1990, 1, 1))
例:查询某一个时间范围内的数据
from datetime import date start_time = date(2018,10,1) end_time = date(2018,10,31) results = Person.objects.filter(birth_date__range=(start_time,end_time))
6、补充
(1)、之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢?
- 答:使用F对象,被定义在django.db.models中。
- 语法如下:
F(属性名)
①例:查询阅读量大于等于评论量的图书。
from django.db.models import F Books.objects.filter(b_read__gte=F('b_comment'))
②可以在F对象上使用算数运算。
例:查询阅读量大于2倍评论量的图书。
Books.objects.filter(b_read__gt=F('b_comment') * 2)
(2)、如果需要实现逻辑或or的查询,那么该怎么处理呢?
- 答:使用Q()对象结合|运算符,Q对象被义在django.db.models中。
- 语法如下:
- Q(属性名__运算符=值)
①例:查询阅读量大于30,并且编号小于5的图书。
Books.objects.filter(b_read__gt=30,id__lt=5) 或 Books.objects.filter(b_read__gt=30).filter(id__lt=5)
改写为Q对象如下。
from django.db.models import Q Books.objects.filter(Q(b_read__gt=50)|Q(id__lt=5))
②Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或。
例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现
Books.objects.filter(Q(b_read__gt=20) | Q(pk__lt=3))
③Q对象前可以使用~操作符,表示非not。
例:查询编号不等于3的图书。
Books.objects.filter(~Q(id=3))
7、聚合函数
使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg 平均,Count 数量,Max 最大,Min 最小,Sum 求和,被定义在django.db.models中。
- 使用count时一般不使用aggregate()过滤器。
①例:查询图书的总阅读量。
from django.db.models import Sum BookInfo.objects.aggregate(Sum('bread'))
- 注意aggregate的返回值是一个字典类型,格式如下:
{‘属性名__聚合类小写’:值}- 如:{‘b_read__sum’:3}
②例:查询图书总数。
BookInfo.objects.count()阅读更多
- [django]入门教程4:操作数据库
- GSAP JS基础教程--TweenLite操作元素的相关属性
- django数据库操作-增删改查-多对多关系以及一对多(外键)关系
- Laravel入门教程(四)- 数据库操作之 - 查询构造器
- Python的Django框架中使用SQLAlchemy操作数据库的教程
- PHP Lumen - 入门教程 - 操作数据库
- 凡哥OpenCV基础入门教程(跳一跳专题)-CH1.1-读入图片并显示图片的相关属性
- 数据库调优教程(六) 索引的相关操作
- 数据库MYSQL入门教程(2)——数据库操作指令
- Django基础篇之数据库选择及相关操作
- Laravel入门教程(三)- 数据库操作 DB facade
- Django原子性更新数据库——数据库表中属性的自增/自减操作
- python django 增删改查操作 数据库Mysql
- 数据库调优教程(六) 索引的相关操作
- MongoDB入门教程(包含安装、常用命令、相关概念、使用技巧、常见操作等)
- Django数据库基本增删改查操作
- MongoDB入门教程之细说MongoDB数据库的增删查改操作
- 06_传智播客hibernate教程_完善HibernateUtil类及hql查询入门 &&07_传智播客hibernate教程_实体类或属性名与数据库关键字冲突问题
- django数据库基本操作-增删改查(tip)-基本
- django数据库基本操作增删改查