准备知识:__str__ 把对象变成字符串。如果想要对象是字符串就去类里加此方法
queryset是ORM中的类型,而下面查询返回的queryset类型的数据是我们看不懂的,因此可以借用__str__方法看到我们想要的数据
queryset和model对象的区别:<queryset[model对象,model对象]>
model可以通过.获取属性
一:API查询
<1> all():
作用:查询所有结果
调用者:objects管理器
返回值:queryset
book_list=Book.objects.all() #查询所有表记录 # 查询出来的数据是这样一种类型QuerySet 类似列表,[obj1,obj2,obj3....]。我们说的models对象就是这里的对象 # book_list[0].title #获取属性值
ret=Book.objects.all() print(ret) # <QuerySet [<Book: GO>, <Book: linux>, <Book: 北京折叠>, <Book: 三体>, <Book: 追风筝的人>, <Book: 乱世佳人>]>
我们已经在类里添加__str__方法,因此返回的直接是obj.title
<2> filter(**kwargs):
作用:它包含了与所给筛选条件相匹配的对象
调用者:objects管理器
返回值:queryset
ret=Book.objects.filter(title="linux",price=111) print(ret) # <QuerySet [<Book: linux>]>
<3> get(**kwargs):
作用:返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
调用者:objects管理器
返回值:返回查询到model对象 (注意:查询结果有且只有一个才执行)
ret=Book.objects.get(title="linux") print(ret.title) # linux
<4> exclude(**kwargs):
作用:它包含了与所给筛选条件不匹配的对象
调用者:objects管理器
返回值:queryset
查询所有不等于111的
ret=Book.objects.exclude(price=111)
<5> order_by(*field):
作用:对查询结果排序
调用者:由queryset对象调用
返回值:queryset
ret=Book.objects.all().order_by("price")升序 ret=Book.objects.all().order_by("-price","-nid")降序 ret=Book.objects.all().order_by("-price","-nid").first()获取最大的那个---链式操作
<6> reverse():
作用:对查询结果反向排序
调用者:由queryset对象调用
返回值:queryset
Book.objects.all().order_by("price").reverse()
<8> count():
作用:返回数据库中匹配查询(QuerySet)的对象数量。
调用者:由queryset对象调用
返回值:返回int
ret=Book.objects.all().count()
<9> first():
作用:返回第一条记录
调用者:由queryset对象调用
返回值:返回查询到model对象
fbook=Book.objects.all()[0] 相当于: fbook=Book.objects.all().first() # lbook=Book.objects.all().last()
<10> last():
作用:返回最后一条记录
调用者:由queryset对象调用
返回值:返回查询到model对象
<11> exists():
作用:如果QuerySet包含数据,就返回True,否则返回False
调用者:由queryset对象调用
返回值:布尔值
is_exist=Book.objects.all().exists() #可以判断有没有数据,所以没必要查看所有的数据,只要查看第一行是否有数据就行,所以,这里相当于select * from 表 limint 1 if is_exist: print("OK")
<12> values(*field): (重点)
作用:返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
调用者:由queryset对象调用
返回值:queryset
values的源码类似于下面: ret=[] for obj in Book.objects.all(): temp={ "title":obj.title, "price":obj.price } ret.append(temp) 所以ret里面是[{"title":obj.title},{}] 列表里是字典
ret=Book.objects.all().values("title","price") # queryset [{"title":"linux"},{"title":"python"},...] 取对应字段的那一列的数据 print(ret) # <QuerySet [{'title': 'GO'}, {'title': 'linux'}, {'title': '北京折叠'}, {'title': '三体'}, {'title': '追风筝的人'}, {'title': '乱世佳人'}]>
我们已经在类里添加__str__方法,因此返回的直接是obj.title
<13> values_list(*field):
作用:它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
调用者:由queryset对象调用
返回值:queryset
ret=Book.objects.all().values_list("title","price") print(ret) # <QuerySet [('GO',), ('linux',), ('北京折叠',), ('三体',), ('追风筝的人',), ('乱世佳人',)]> 列表里是元祖
<14> distinct():
作用:从返回结果中剔除重复纪录
调用者:由queryset对象调用
返回值:queryset
ret=Book.objects.all().values("title").distinct() print(ret) 分析:一张表里是没有重复的,因为主键id不同啊,那distinct存在的意义呢? 我们可以结合value,value是获取某列的数据,这样不就可以去重了么?
二:模糊查询-基于双下划线
__isnull:判断是否为空
案例:
1:查询价格大于200的书籍
ret=Book.objects.filter(price__gt=200) #大于 ret=Book.objects.filter(price__gte=200) #大于等于
2: 查询书籍名称以py开头的所有的书籍的名称
ret=Book.objects.filter(title__startswith="py").values("title") ret=Book.objects.filter(title__istartswith="py").values("title") ret=Book.objects.filter(title__contains="p").values("title")#包含p的所有书籍 print(ret) # <QuerySet [{'title': 'pycharm'}, {'title': 'python'}]> __startswith和__istartswith的区别? __istartswith不区分大小写
3:查询2017年7月份的所有的书籍
ret=Book.objects.filter(pub_date__year=2017,pub_date__month=7) print(ret) # <QuerySet []>
其他案例:
1 查询苹果出版社出版过的价格大于200的书籍 Book.objects.filter(publish="苹果出版社",price__gt=200) 2 查询2017年8月出版的所有以py开头的书籍名称 Book.objects.filter(pub_date__year=2017,pub_date__month=8,title__startswith="py") 3 查询价格为50,100或者150的所有书籍名称及其出版社名称 Book.objects.filter(price__in=[50,100,150]).values("title","publish") # [{},{}] 4 查询价格在100到200之间的所有书籍名称及其价格 Book.objects.filter(price__range=[100,200]).values("title","price") 5 查询所有人民出版社出版的书籍的价格(从高到低排序,去重) Book.objects.filter(publish="人民出版社").order_by("-prcie").values("price").distinct() [obj3,obj1,obj2]----->[{"prcie":200},{"prcie":100}]
参考:官方文档