Django 自学笔记兼学习教程第5章第2节——进阶查询——Queryset

点击查看教程总目录

Queryset相关内容其实蛮多的,本文只介绍一些常用的,详细的推荐查询官方文档:queryset-api

0 - 数据示例

为了方便本文后面内容举例,这里先展示下models.py和数据库表内容,

myapp/models.py在本章第一节,如下:

from django.db import models

class Person(models.Model):
gender = (
('male', '男'),
('female', '女'),
) name = models.CharField(max_length=60)
sex = models.CharField(max_length=32, choices=gender, default='男')
age = models.IntegerField()

数据库表Person如下

id name sex age
2 Li Hua male 20
3 Big Shuang male 24
4 Xiao Hong female 21
5 Xiao Hua female 19
6 Ellen female 20
7 Zhang Sirui female 22
8 Alex male 23
9 Zhao Wen female 24
10 Sun Wu male 18
11 Qian Kong male 22

可通过在Django下的交互式命令行,运行以下代码,快速生成数据库数据。

>>> from myapp.models import Person
>>> info_list = [
["Li Hua", "male", 20],
["Big Shuang", "male", 24],
["Xiao Hong", "female", 21],
["Xiao Hua", "female", 19],
["Ellen", "female", 20],
["Zhang Sirui", "female", 22],
["Alex", "male", 23],
["Zhao Wen", "female", 24],
["Sun Wu", "male", 18],
["Qian Kong", "male", 22],
]
>>> for info in info_list:
name, sex, age = info
pi = Person(name=name, sex=sex, age=age)
pi.save()

1 - 查询方法

filter

个人最常用的查询方法是filter,可以简单理解为按条件查找(筛选),该方法返回一个Queryset对象,

其语法为OneModel.objects.filter(**kwargs),其中OneModel为要查询的模型名,kwargs为查询条件,接受关键词(keyword)参数, 该关键字具体格式见本文第二部分。

使用举例如下(在Django下的交互式命令行里执行代码)

>>> from myapp.models import Person
>>> age_20 = Person.objects.filter(age=20)
>>> age_20
<QuerySet [<Person: Person object (2)>, <Person: Person object (6)>]>
>>> age_20[0]
<Person: Person object (2)>
>>> age_20[0].name
'Li Hua'

get

返回与给定查找参数唯一匹配的对象,

注意:如果查找条件能找到多个结果或者0个结果,该方法都会报错。

其语法为OneModel.objects.get(**kwargs)

使用举例如下(承接上文命令行中代码)

>>> lihua = Person.objects.get(name="Li Hua")
>>> lihua.name
'Li Hua'
>>> lihua.age
20

all

获取数据库表所有数据(严格来讲,这已经不算查询方法了)。

其语法为OneModel.objects.all()

示例如下

>>> persons = Person.objects.all()
>>> for p in persons: print(p.name, p.age, end=",")
>>> print()
Li Hua 20,Big Shuang 24,Xiao Hong 21,Xiao Hua 19,Ellen 20,Zhang Sirui 22,Alex 23,Zhao Wen 24,Sun Wu 18,Qian Kong 22,

raw

执行一个SQL查询,并返回一个django.db.models.query.RawQuerySet实例。

RawQuerySet实例可以像普通的QuerySet一样遍历以提供对象实例。

示例如下

>>> persons_above22 = Person.objects.raw("select * from myapp_person where age>22")
>>> for p in persons_above22: print(p.id, p.name, p.sex, p.age)
3 Big Shuang male 24
8 Alex male 23
9 Zhao Wen female 24

2 字段查找格式(Field lookups)

本文第一部分的filter和get方法,都是接受**kwargs作为查询条件来搜索的。

这个又称为字段查找(Field lookups),效果为指定SQL WHERE子句内容。

第一部分只展示了最简单的查询条件:严格相等。

如果要查找一些其他的条件,比如说年龄大于20岁,名字里面含有a字母等等。

则需要使用某种方法标明这个条件,django里面通过字段查找类型(lookup type)实现了这种方法。

给字段field指定查找类型lookup的语法如下

field__lookup

不指定时默认查找类型为精确exact,

即以下两句效果等同

lihua = Person.objects.get(name="Li Hua")
lihua = Person.objects.get(name__exact="Li Hua")

对应的sql为

SELECT * from myapp_person WHERE name = 'Li Hua';

这里介绍一些常用的查找类型,更多请查阅官方文档:field-lookups

  • iexact: 忽略大小写
  • contains: 查询包含指定模式的字段,(区分大小写)。
  • icontains: 查询包含指定模式的字段,(忽略大小写)。

注:由于SQLite不支持区分大小写的LIKE操作符,所以SQLite中contains效果为icontains。

  • in: 在给定的可迭代对象中,如列表、元组或查询集,还有字符串。
  • gt: 大于(记忆技巧:greater than首字母)。
  • gte: 大于或等于,(记忆技巧:greater than equal首字母)。
  • lt: 小于(记忆技巧:less than首字母)。
  • lte: 小于或等于,(记忆技巧:less than equal首字母)。
  • startswith: 开头匹配,(区分大小写)。
  • istartswith: 开头匹配,(忽略大小写)。
  • endswith: 结尾匹配,(区分大小写)。
  • iendswith: 结尾匹配,(忽略大小写)。
  • regex: 正则匹配,(区分大小写)。
  • iregex: 正则匹配,(忽略大小写)。

注: 正则表达式语法是Python的re模块的语法。

举例演示:

>>> name_a = Person.objects.filter(name__icontains="a")
>>> for p in name_a: print(p.name, end=", ")
>>> print()
Li Hua, Big Shuang, Xiao Hong, Xiao Hua, Zhang Sirui, Alex, Zhao Wen, Qian Kong,
>>> age_lte_20 = Person.objects.filter(age__lte=20)
>>> for p in age_lte_20: print(p.name, p.age, end=", ")
>>> print()
Li Hua 20, Xiao Hua 19, Ellen 20, Sun Wu 18,

注:由于查找类型语法,是通过在字段名后面加两个下划线后声明的。

所以Django的模型中的属性字段名不可有两个下划线。

3 quertset 基础操作

使用filter和all方法获取到的都是一个queryset对象,

所以我们也需要掌握该对象一些常用的方法和操作。

首先,queryset对象是一个可迭代对象,

这意味着它可以使用for循环遍历。

同时queryset对象也可以使用切片操作。

还可以使用len、list等函数获取其对应结果。

queryset对象常用方法:

  • order_by: 按指定字段排序,可指定多个字段(从前往后按字段来排序)。

    默认升序,在字段名前加负号则降序。

使用示例:

>>> persons = Person.objects.all()
>>> persons_sorted_age = persons.order_by("age")
>>> for p in persons_sorted_age: print(p.name, p.age, end=", ")
>>> print()
Sun Wu 18, Xiao Hua 19, Li Hua 20, Ellen 20, Xiao Hong 21, Zhang Sirui 22, Qian Kong 22, Alex 23, Big Shuang 24, Zhao Wen 24,
>>> persons_sorted_age_descending = persons.order_by("-age")
>>> for p in persons_sorted_age_descending: print(p.name, p.age, end=", ")
>>> print()
Big Shuang 24, Zhao Wen 24, Alex 23, Zhang Sirui 22, Qian Kong 22, Xiao Hong 21, Li Hua 20, Ellen 20, Xiao Hua 19, Sun Wu 18,
  • order_by: 按指定字段排序,可指定多个字段(从前往后按字段来排序)。

    默认升序,在字段名前加负号则降序。

4 操作符

本文第二部分介绍了字段查找的基础格式。

且查询条件可以写多个,代表查找同时遵循这些条件的结果。

那么有一个问题,如果要查询满足A或B的结果,那么上面写法就不够用了。

Django实现了一个可以封装SQL表达式的对象Q,该对象在django.db.models中。

Q可以封装一个查询条件,

Q对象之间可以使用|(或)和&(且)符号,进行逻辑运算。

不仅可以实现上面指出的或查询问题,还可以可以定义和重用查询条件。

示例如下

>>> name_contains_a = Q(name__icontains="a")
>>> age_above_22 = Q(age__gt=22)
>>> and_res = Person.objects.filter(name_contains_a & age_above_22)
>>> for p in and_res: print(p.name, p.age, end=",")
>>> print()
Big Shuang 24,Alex 23,Zhao Wen 24,
>>> or_res = Person.objects.filter(name_contains_a | age_above_22)
>>> for p in or_res: print(p.name, p.age, end=",")
>>> print()
Li Hua 20,Big Shuang 24,Xiao Hong 21,Xiao Hua 19,Zhang Sirui 22,Alex 23,Zhao Wen 24,Qian Kong 22,

Django笔记&教程 5-2 进阶查询——Queryset的更多相关文章

  1. Django笔记&教程 6-4 forms进阶操作,重写forms方法

    Django 自学笔记兼学习教程第6章第4节--forms进阶操作,重写forms方法 点击查看教程总目录 1 - 重写clean方法 在本章第三节中,我们举了个注册学生账号的例子,里面我们使用模型来 ...

  2. Django笔记&教程 总目录

    本篇博客只有目录,正文内容在目录章节链接的博客里 除目录本身外,没有链接的章节,说明内容还没开始编辑 本项目笔记仍在不断创作中,还有些内容会根据自身所学不断更新完善 本项目主要为markdwon文档, ...

  3. Django笔记&教程 5-1 基础增删查改

    Django 自学笔记兼学习教程第5章第1节--基础增删查改 点击查看教程总目录 第四章介绍了模型类models.Model和创建模型,相当于介绍了数据库表和如何创建数据库表. 这一章将介绍如何使用模 ...

  4. Django笔记&教程 7-3 拓展CBVs(Class-based views)

    Django 自学笔记兼学习教程第7章第3节--拓展CBVs(Class-based views) 点击查看教程总目录 一般而言,直接使用原生的Class-based views,能展现的样式和内容是 ...

  5. Django笔记&教程 0-1 前言

    Django 自学笔记兼学习教程第0章第1节--前言 点击查看教程总目录 1 最初的想法 自学Django已经有一段时间了,自认收获不少,学的还算可以,然而实际去做项目写代码的时候,很多用法记得不清, ...

  6. Django笔记&教程 0-2 框架版本与相关工具

    Django 自学笔记兼学习教程第0章第2节-- 框架版本与相关工具 点击查看教程总目录 1 版本 python: 3.6.5 Django: 2.2.11 (有些地方我也会对比下各种版本的区别) 安 ...

  7. Django笔记&教程 1-1 一 新建项目

    Django 自学笔记兼学习教程第1章第1节--一 新建项目 点击查看教程总目录 1- 命令行新建Django项目 新建项目命令(project_name处为项目名) django-admin sta ...

  8. Django笔记&教程 1-2 二 常用配置

    Django 自学笔记兼学习教程第1章第2节--二 常用配置 点击查看教程总目录 新手建议简单浏览本文,不理解的建议跳过,不要强行理解. Django的设置涉及多个模块,需要了解Django的一些相关 ...

  9. Django笔记&教程 2-1 URL与View关系

    Django 自学笔记兼学习教程第2章第1节--URL与View关系 点击查看教程总目录 参考:how-django-processes-a-request 1- Django处理请求(request ...

随机推荐

  1. Initialization failed for 'https://start.spring.io' Please check URL, network and proxy settings.

    今天新建一个spring web项目,发现报错了.问题如下. 排除了网络问题,找到了解决办法.打开设置,点击check connection 输入 https://start.spring.io 点击 ...

  2. Docker-Java限制cpu和内存及浅析源码解决docker磁盘挂载失效问题

    需求 之前工作流的运行都是用的docker-java提供的api拉起的docker容器直接跑服务,但是最新线上的新业务资源消耗较大,单个容器如果不加控制,CPU和内存都会拉满,导致服务器莫名宕机事故的 ...

  3. Linux命令行:free

                  total        used        free      shared  buff/cache   availableMem:           251G   ...

  4. 浅谈机(J)惨(C)技巧——从入门到精通(?)

    JC总是无聊的机房中有意思的一个瞬间... 比如: 这个杰作由 ZSWBWYX 完成 你认为这只是AK-IOI吗?不!注意用户名...也是此人的杰作. 所以,在险恶的机房里,一定要保护好自己的账号. ...

  5. FastAPI(64)- Settings and Environment Variables 配置项和环境变量

    背景 在许多情况下,应用程序可能需要一些外部设置或配置,例如密钥.数据库凭据.电子邮件服务凭据等. 大多数这些设置都是可变的(可以更改),例如数据库 URL,很多可能是敏感数据,比如密码 出于这个原因 ...

  6. IO之字节流

    什么是字节流 像操作 图片 视频 mp4 文档(里面可能有图片) 等等 注意点 必须使用try catch finally 来包 不用throws(流是要关闭的 如果中途抛错 throws 无法将流关 ...

  7. 从零入门 Serverless | 一文搞懂函数计算及其工作原理

    作者 | 孔德慧(夏莞) 阿里云函数计算开发工程师 什么是函数计算 大家都了解,Serverless 并不是没有服务器,而是开发者不再需要关心服务器.下图是一个应用从开发到上线的对比图: 在传统 Se ...

  8. Serverless X OpenKruise 部署效率优化之道

    作者 | 许成铭(竞霄) Serverless 作为云计算的最佳实践.云原生发展的方向和未来演进趋势,其核心价值在于快速交付.智能弹性.更低成本.SAE(Serverless 应用引擎)作为首款面向应 ...

  9. Python Pandas的使用 !!!!!详解

     Pandas是一个基于python中Numpy模块的一个模块 Python在数据处理和准备⽅⾯⼀直做得很好,但在数据分析和建模⽅⾯就差⼀些.pandas帮助填补了这⼀空⽩,使您能够在Python中执 ...

  10. 详解build-gradle文件

    目录 gradle 两个build.gradle文件 最外层目录下的build.gradle文件 jcenter dependencies闭包 app目录下的build.gradle文件 com.an ...