Django笔记&教程 5-2 进阶查询——Queryset
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的更多相关文章
- Django笔记&教程 6-4 forms进阶操作,重写forms方法
Django 自学笔记兼学习教程第6章第4节--forms进阶操作,重写forms方法 点击查看教程总目录 1 - 重写clean方法 在本章第三节中,我们举了个注册学生账号的例子,里面我们使用模型来 ...
- Django笔记&教程 总目录
本篇博客只有目录,正文内容在目录章节链接的博客里 除目录本身外,没有链接的章节,说明内容还没开始编辑 本项目笔记仍在不断创作中,还有些内容会根据自身所学不断更新完善 本项目主要为markdwon文档, ...
- Django笔记&教程 5-1 基础增删查改
Django 自学笔记兼学习教程第5章第1节--基础增删查改 点击查看教程总目录 第四章介绍了模型类models.Model和创建模型,相当于介绍了数据库表和如何创建数据库表. 这一章将介绍如何使用模 ...
- Django笔记&教程 7-3 拓展CBVs(Class-based views)
Django 自学笔记兼学习教程第7章第3节--拓展CBVs(Class-based views) 点击查看教程总目录 一般而言,直接使用原生的Class-based views,能展现的样式和内容是 ...
- Django笔记&教程 0-1 前言
Django 自学笔记兼学习教程第0章第1节--前言 点击查看教程总目录 1 最初的想法 自学Django已经有一段时间了,自认收获不少,学的还算可以,然而实际去做项目写代码的时候,很多用法记得不清, ...
- Django笔记&教程 0-2 框架版本与相关工具
Django 自学笔记兼学习教程第0章第2节-- 框架版本与相关工具 点击查看教程总目录 1 版本 python: 3.6.5 Django: 2.2.11 (有些地方我也会对比下各种版本的区别) 安 ...
- Django笔记&教程 1-1 一 新建项目
Django 自学笔记兼学习教程第1章第1节--一 新建项目 点击查看教程总目录 1- 命令行新建Django项目 新建项目命令(project_name处为项目名) django-admin sta ...
- Django笔记&教程 1-2 二 常用配置
Django 自学笔记兼学习教程第1章第2节--二 常用配置 点击查看教程总目录 新手建议简单浏览本文,不理解的建议跳过,不要强行理解. Django的设置涉及多个模块,需要了解Django的一些相关 ...
- Django笔记&教程 2-1 URL与View关系
Django 自学笔记兼学习教程第2章第1节--URL与View关系 点击查看教程总目录 参考:how-django-processes-a-request 1- Django处理请求(request ...
随机推荐
- 你说要你想玩爬虫,但你说你不懂Python正则表达式,我信你个鬼,那你还不来看看?
前言 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数. re.mat ...
- NOIP 模拟 六十九
0+30+40+90, 菜..... T1 取石子 考试扔了将近两个小时,最后也没有回忆起博弈论的相关内容.. 现在只会50pts.正解待补. #include<bits/stdc++.h> ...
- 缓冲区溢出利用与ShellCode编写
一.实验目的 熟悉编写shellCode的流程 掌握缓冲区溢出的利用 二.实验环境 系统环境:Windows环境 软件环境:C++ ,缓冲区溢出文件链接 三.实验原理 要实施一次有效的缓冲区溢出攻击, ...
- 从零入门 Serverless | 一文搞懂函数计算及其工作原理
作者 | 孔德慧(夏莞) 阿里云函数计算开发工程师 什么是函数计算 大家都了解,Serverless 并不是没有服务器,而是开发者不再需要关心服务器.下图是一个应用从开发到上线的对比图: 在传统 Se ...
- redis学习笔记-01 string类型命令
一.set key value set joker 123456 #设定key为joker,value为123456的数据 二.keys * keys * #用于查看该数据库中所有的key值 三.se ...
- HAOI2012高速公路bzoj2752 (线段树,数学)
题目大意: 给定一个长度为n的链,一共m次操作 对于每次操作 \(C\ l\ r\ x\)表示将第l个点到第r个点之间的所有道路的权值增加v \(Q\ l\ r\)在第l个到第r个点里等概率随机取出两 ...
- pycharm上的python虚拟环境移到离线机器上
Pycharm的Terminal 中执行: 查看现有的包到requirements.txt中 pip freeze > requirements.txt 生成依赖包 D:\machangwei\ ...
- BG的本性
BG的本性 更舒适的体验 算法一: 我还会暴力!模拟一下 复杂度 \(O(nm)\), 期望得分10 算法二: 用线段树优化枚举,直接找可行点 复杂度 \(O(\mathrm{ans} \log_2 ...
- 2021.3.10--vj补题
B - Saving the City cf--1443B Bertown is a city with nn buildings in a straight line. The city's sec ...
- Java(7)流程控制语句中的for、while、do while循环
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201543.html 博客主页:https://www.cnblogs.com/testero ...