您的位置:首页 > 数据库

Django入门教程(十三)数据库相关操作(增删改查、属性与常量、属性与属性、聚合)

2018-11-01 10:44 627 查看

这里专门来讲一下数据库接口相关的接口(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()
阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: