QuerySet,查询集,即从数据库中查询的到的集合。这一节主要学习与QuerySet相关的一些指令。
首先我们新建一个名为learn_queryset的项目,在其中创建应用blog并修改settings(测试指令时需要使用)
修改blog/manage.py为:
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete = models.CASCADE)
#从django1.9开始ForeignKey的on_delete参数就是必须的,如果没写会报错
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self):
return self.headline
8-1 新建对象
创建对象有以下几种方法:
(1)Person.objects.create(name = 'name', age = age)
(2)p = Person(name = 'name', age = age)
p.save()
(3)p = Person(name = 'name')
p.age = age
p.save()
(4)Person.objects.get_or_create(name = 'name', age = age)
这种方法可以防止重复,它返回一个元组,第一个为Person对象,第二个为True或者False,没有创建返回True,已经存在返回False。
8-2 获取对象
(1)Person.objects.all()
获取全部对象
(2)Person.objects.all()[ : 10]
获取10个人,切片可以节约内存
切片不支持负索引,可以用reverse函数实现
Person.objects.all().reverse()[ : 2] 获取最后两个
(3)Person.objects.get(name = 'name')
获取名为name的一个对象(如果有两个重名的对象会报错)
get只能获取一个对象,如果想获取满足条件的一些对象需要用filter
(4)Person.objects.filter(name = 'name')
名称为严格等于name的一些人
(5)Person.objects.filter(name__iexact = 'name')
名称符合name但不区分大小写
(6)Person.objects.filter(name__contains = 'name')
名称中包含'name'的人
(7)Person.objects.filter(name__icontains = 'name')
名称中包含'name'但不区分大小写
(8)Person.objects.filter(name__regex = '^abc')
正则表达式查询
(9)Person.objects.filter(name__iregex = '^abc')
正则表达式不区分大小写
排除某些条件:
(QuerySet支持链式查询)
(10)Person.objects.exclude(name__contains = 'name')
排除包含name的对象
(11)Person.objects.filter(name__contains = 'name').exclude(age = 23)
找出名称含有name但年龄不是23岁的
8-3 删除对象
使用函数delete()
(1)Person.objects.all().delete()
删除全部数据
(2)Person.objects.get(name = 'name').delete()
删除名为name的对象
(3)Person.objects.filter(name__contains = 'name').delete()
删除包含name的一些对象
8-4 去重
一般情况下QuerySet中不会出现重复,但当跨越多张表进行检索后合并到一起就可能会出现重复,可以使用distinct函数去重
qs = qs.distinct()
8-5 更新
(1)批量更新
Person.objects.filter(name__contains = 'abc').update(name = 'xxx') #名称中包含abc的都改成xxx
(2)单个更新,适用于get(),get_or_create(),update_or_create()等得到的obj
p = Author.objects.get(name = 'Youzhu')
p.name = 'Zhoumujing'
p.email = 'zmj@163.com'
p.save() # !!一定要记得保存
8-6 迭代
QuerySet是可迭代的
es = Entry.objects.all()
for e in es:
print(e.headline)
8-7 排序
将查询结果排序:
Author.objects.all( ).order_by('name')
Author.objects.all( ).order_by('-name') #在前面加上负号就可实现倒序排序
8-8 QuerySet可以用pickle序列化到硬盘再读取出来
(这里没太懂……)
>>> import pickle
>>> query = pickle.loads(s) # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query # Restore the original 'query'.
8-9 其他注意事项
(1)如果只是检查Entry中是否有对象,应该用exists( )函数
Entry.objects.all( ).exists( )
(2)用len(es)可以得到Entry的数量,查询数量推荐使用Entry.objects.count( )
(3)list(es)可以将QuerySet强行变成列表
教程链接:Django QuerySet API