本文略长,读完约需十分钟。当做复习笔记效果更佳。

查询操作:

数据查询是数据库操作中一个非常重要的技术。查询一般就是使用filter、exclude以及get三个方法来实现。我们可以在调用这些方法的时候传递不同的参数来实现查询需求。在ORM层面,这些查询条件都是使用field+__+condition的方式来使用的。以下将那些常用的查询条件来一一解释。

1.exact:在底层会被翻译成=。使用精确的=进行查找。如果提供的是一个None,那么在SQL层面就是被解释为NULL。示例代码如下:

article = Article.objects.get(id__exact=14)

article = Article.objects.get(id__exact=None)

以上的两个查找在翻译为SQL语句为如下:

select ... from article where id=14;

select ... from article where id IS NULL;

2.iexact:在底层会被翻译成LIKE。示例代码如下:

article = Article.objects.filter(title__iexact='hello world')

那么以上的查询就等价于以下的SQL语句:

select ... from article where title like 'hello world';

注意上面这个sql语句,因为在MySQL中,没有一个叫做ilike的。所以exact和iexact的区别实际上就是LIKE和=的区别,在大部分collation=utf8_general_ci情况下都是一样的(collation是用来对字符串比较的)。

注意:

1.LIKE和=:大部分情况下都是等价的,只有少数情况下是不等价的。

2.exict和iexact:他们的区别其实就是LIKE和=的区别,因为exact会被翻译成=,而iexact会被翻译成LIKE。

3.因为field__exact=xxx其实等价于filed=xxx,因此我们直接使用filed=xxx就可以了,并且因为大部分情况exact和iexact又是等价的,因此我们以后直接使用field=xxx就可以了。

QuerySet.query:query可以用来查看这个ORM查询语句最终被翻译成的SQL语句。但是query只能被用在QuerySet对象上,不能用在普通的ORM模型上。因此如果你的查询语句是通过get来获取数据的,那么就不能使用query,因为get返回的是满足条件的ORM模型,而不是QuerySet。如果你是通过filter等其他返回QuerySet的方法查询的,那么就可以使用query。

contains:使用大小写敏感的判断,某个字符串是否在指定的字段中。这个判断条件会使用大小敏感,因此在被翻译成SQL语句的时候,会使用like binary,而like binary就是使用大小写敏感的。

icontains:使用大小写不敏感的判断,某个字符串是否被包含在指定的字段中。这个查询语句在被翻译成SQL的时候,使用的是like,而like在MySQL层面就是不区分大小写的。

contains和icontains:在被翻译成SQL的时候使用的是%hello%,就是只要整个字符串中出现了hello都能过够被找到,而iexact没有百分号,那么意味着只有完全相等的时候才会被匹配到。

in:可以直接指定某个字段的是否在某个集合中。示例代码如下:

articles = Article.objects.filter(id__in=[1,2,3])

也可以通过其他的表的字段来判断是否在某个集合中。示例代码如下:

categories = Category.objects.filter(article__id__in=[1,2,3])

如果要判断相关联的表的字段,那么也是通过__来连接。并且在做关联查询的时候,不需要写models_set,直接使用模型的名字的小写化就可以了。比如通过分类去查找相应的文章,那么通过article__id__in就可以了,而不是写成article_set__id__in的形式。当然如果你不想使用默认的形式,可以在外键定义的时候传递related_query_name来指定反向查询的名字。示例代码如下:

class Category(models.Model):

name = models.CharField(max_length=100)

class Meta:

db_table = 'category'

class Article(models.Model):

title = models.CharField(max_length=200)

content = models.TextField()

cateogry = models.ForeignKey("Category",on_delete=models.CASCADE,null=True,related_query_name='articles')

class Meta:

db_table = 'article'

因为在cateogry的ForeignKey中指定了related_query_name为articles,因此你不能再使用article来进行反向查询了。这时候就需要通过articles__id__in来进行反向查询。

反向查询是将模型名字小写化。比如article__in。可以通过related_query_name来指定自己的方式,而不使用默认的方式。反向引用是将模型名字小写化,然后再加上_set,比如article_set,可以通过related_name来指定自己的方式,而不是用默认的方式。

并且,如果在做反向查询的时候,如果查询的字段就是模型的主键,那么可以省略掉这个字段,直接写成article__in就可以了,不需要这个id了。

in不仅仅可以指定列表/元组,还可以为QuerySet。比如要查询“文章标题中包含有hello的所有分类”,那么可以通过以下代码来实现:

articles = Article.objects.filter(title__icontains='hello')

categories = Category.objects.filter(articles__in=articles)

for cateogry in categories:

print(cateogry)

8.gt、gte、lt、lte:代表的是大于、大于等于、小于、小于等于的条件。示例代码如下:

articles = Article.objects.filter(id__lte=3)

9.startswith、istartswith、endswith、iendswith:表示以某个值开始,不区分大小写的以某个值开始、以某个值结束、不区分大小写的以某个值结束。示例代码如下:

articles = Article.objects.filter(title__endswith="hello")

10.关于时间的查询条件:

range:可以指定一个时间段。并且时间应该标记为

aware时间,不然django会报警告。示例代码如下:

start_time = make_aware(datetime(year=2020,month=4,day=4,hour=17,minute=0,second=0))

end_time = make_aware(datetime(year=2020,month=4,day=4,hour=18,minute=0,second=0))

articles = Article.objects.filter(create_time__range=(start_time,end_time))

print(articles.query)

print(articles)

date:用年月日来进行过滤。如果想要使用这个过滤条件,那么前提必须要在

MySQL中添加好那些时区文件。如何添加呢?参考教案。示例代码如下:

articles = Article.objects.filter(create_time__date=datetime(year=2020,month=4,day=4))

year/month/day:表示根据

年/月/日进行查找。示例代码如下:

articles = Article.objects.filter(create_time__year__gte=2020)

week_day:根据星期来进行查找。1表示星期天,7表示星期六,2-6代表的是星期一到星期五。比如要查找星期三的所有文章,那么可以通过以下代码来实现:

articles = Article.objects.filter(create_time__week_day=4)

time:根据分时秒来进行查找。如果要具体到秒,一般比较难匹配到,可以使用区间的方式来进行查找。区间使用

range条件。比如想要获取17时/10分/27-28秒之间的文章,那么可以通过以下代码来实现:

start_time = time(hour=17,minute=10,second=27)

end_time = time(hour=17,minute=10,second=28)

articles = Article.objects.filter(create_time__time__range=(start_time,end_time))

聚合函数:

如果你用原生SQL,则可以使用聚合函数来提取数据。比如提取某个商品销售的数量,那么可以使用Count,如果想要知道商品销售的平均价格,那么可以使用Avg。聚合函数是通过aggregate方法来实现的。1.所有的聚合函数都是放在django.db.models下面。2.聚合函数不能够单独的执行,需要放在一些可以执行聚合函数的方法下面中去执行。比如aggregate。示例代码如下:

result = Book.objects.aggregate(Avg("price"))

3.聚合函数执行完成后,给这个聚合函数的值取个名字。取名字的规则,默认是filed+__+聚合函数名字形成的。比如以上代码形成的名字叫做price__avg。如果不想使用默认的名字,那么可以在使用聚合函数的时候传递关键字参数进去,参数的名字就是聚合函数执行完成的名字。实示例代码如下:

result = Book.objects.aggregate(avg=Avg("price"))

以上传递了关键字参数avg=Avg("price"),那么以后Avg聚合函数执行完成的名字就叫做avg。4.aggregate:这个方法不会返回一个QuerySet对象,而是返回一个字典。这个字典中的key就是聚合函数的名字,值就是聚合函数执行后的结果。5.aggregate和annotate的相同和不同:

相同:这两个方法都可以执行聚合函数。

不同:

aggregate

返回的是一个字典,在这个字典中存储的是这个聚合函数执行的结果。

annotate

返回的是一个

QuerySet

对象,并且会在查找的模型上添加一个聚合函数的属性。

aggregate不会做分组,而

annotate会使用

group by子句进行分组,只有调用了

group by子句,才能对每一条数据求聚合函数的值。

6.Count:用来求某个数据的个数。比如要求所有图书的数量,那么可以使用以下代码:

result = Book.objects.aggregate(book_nums=Count("id"))

并且Count可以传递distinct=True参数,用来剔除那些重复的值,只保留一个。比如要获取作者表中,不同邮箱的个数,那么这时候可以使用distinct=True。示例代码如下:

result = Author.objects.aggregate(email_nums=Count('email',distinct=True))

7.Max和Min:求指定字段的最大值和最小值。示例代码如下:

result = Author.objects.aggregate(max=Max("age"),min=Min("age"))

8.Sum:求某个字段值的总和。示例代码如下:

result = BookOrder.objects.aggregate(total=Sum('price'))

aggregate和annotate方法可以在任何的QuerySet对象上调用。因此只要是返回了QuerySet对象,那么就可以进行链式调用。比如要获取2018年度的销售总额,那么可以先过滤年份,再求聚合函数。示例代码如下:

BookOrder.objects.filter(create_time__year=2020).aggregate(total=Sum('price'))

7.F表达式:动态的获取某个字段上的值。并且这个F表达式,不会真正的去数据库中查询数据,他相当于只是起一个标识的作用。比如想要将原来每本图书的价格都在原来的基础之上增加10元,那么可以使用以下代码来实现:

from django.db.models import F

Book.objects.update(price=F("price")+10)

8.Q表达式:使用Q表达式包裹查询条件,可以在条件之间进行多种操作。与/或非等,从而实现一些复杂的查询操作。例子如下:

查找价格大于100,并且评分达到4.85以上的图书:

# 不使用Q表达式的

books = Book.objects.filter(price__gte=100,rating__gte=4.85)

# 使用Q表达式的

books = Book.objects.filter(Q(price__gte=100)&Q(rating__gte=4.85))

查找价格低于100元,或者评分低于4分的图书:

books = Book.objects.filter(Q(price__gte=100)&Q(rating__gte=4.85))

获取价格大于100,并且图书名字中不包含”传“字的图书:

books = Book.objects.filter(Q(price__gte=100)&~Q(name__icontains='传'))

python爬虫 django搜索修改更新数据_一文搞懂Django数据库查询操作相关推荐

  1. python爬虫 django搜索修改更新数据_django_数据库操作—增、删、改、查

    增加 增加数据有两种方法 1> sava >>> from datetime import date >>> book = BookInfo( btitle= ...

  2. python爬虫 django搜索修改更新数据_python应用:Django中更新多个对象数据与删除对象的方法...

    Python是一种解释型脚本语言,可以应用于以下领域: web和Internet开发 科学计算和统计 人工智能 教育 桌面界面开发 软件开发 后端开发 网络爬虫 更新多个对象 例如说我们现在想要将Ap ...

  3. swagger 修改dto注解_一文搞懂Swagger,让你明白用了Swagger的好处!!!

    前后端分离缺陷 了解Swagger之前,需要先知道什么是前后端分离 现在的时代 SpringBoot + VUE 以前的时代 SSM + JSP模板引擎====>后端程序员 前后端分离时代 通过 ...

  4. python语言语句快的标记是什么_一文搞懂Python程序语句

    原标题:一文搞懂Python程序语句 程序流 Python 程序中常用的基本数据类型,包括: 内置的数值数据类型 Tuple 容器类型 String 容器类型 List 容器类型 自然的顺序是从页面或 ...

  5. pythonxpath定位_一文搞懂 XPath 定位

    一文搞懂XPath 定位 XPath (XML Path Language) 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历. XPath定位在爬虫和自动化测试中 ...

  6. python中row是什么意思_一文搞懂Python中的yield

    关注公众号「Python七号」,及时 get Python 技能. yield 可以实现生成器,可以实现协程. 什么是生成器,什么是协程,如果还不了解,可以继续往下看,概念可以不懂,只要理解它的作用和 ...

  7. python可变序列和不可变序列_一文看懂可变序列和不可变序列

    先说点概念 在解释可变/不可变序列之前,先要知道什么是序列?序列就一个个元素有序地排列在一起,像小朋友"排排坐,吃果果"一样. 可变序列就是创建一个序列后,可以改变元素,可以比如成 ...

  8. rest api是什么_一文搞懂什么是RESTful API

    RESTful接口实战 首发公众号:bigsai 转载请附上本文链接 文章收藏在回车课堂 前言 在学习RESTful 风格接口之前,即使你不知道它是什么,但你肯定会好奇它能解决什么问题?有什么应用场景 ...

  9. fseek linux 大文件_一文搞懂Linux系统开发

    文章目录 Linux系统开发会用到什么? C语言基础 shell脚本 慢慢学会使用Makefile 常规Linux系统编程知识都有什么?哪些常用?哪些不常用? 常规Linux编程知识 文件IO 文件与 ...

最新文章

  1. 学以致用七---Centos7.2+python3.6.2+django2.1.1 --搭建一个网站(补充)
  2. ef延迟加载不到导航属性问题
  3. 比特币耶稣Roger Ver:比特币现金是比特币扩容问题的答案
  4. java解析html的table
  5. mysql建用户无密码_mysql建用户和修改密码和忘记密码的解决办法
  6. 深度学习与自然语言处理
  7. cpu占用高 mongo_排查MongoDB CPU使用率高的问题
  8. Java实战项目推荐(包括微服务、电商、支付项目、后台管理系统等)!
  9. 手写一个识别旺旺/千牛,手机在线/电脑在线状态的小工具
  10. 关于程序员的面试于自我介绍模板
  11. Hive 知识体系保姆级教程
  12. 如何备份android,如何备份安卓手机系统
  13. 厉害了!百度智能云NIRO Pro智能机器人半年内连获三项产品设计大奖
  14. 手动晶圆切割贴膜机-8寸12寸晶圆减薄划片机
  15. 西湖论剑2021杂项(misc)--YUSA的小秘密
  16. 7个少有人知的资源宝藏网站,浏览器瞬间爆棚!速速收藏
  17. 手把手教你如何将chatgpt接入微信公众号
  18. PIP更新问题丨You should consider upgrading via the 'python -m pip install —upgrade pip' command.
  19. 编译器,解释器,预编译器之间的关系
  20. Java学习 day11 (继承与多态)接口、多态

热门文章

  1. IT运维管理员如何写好一份年终总结?
  2. 代码编辑神器VIM(附我写acm程序时的配置)(转)
  3. 判断输入是否为汉字的方法
  4. 关闭VMware 不用的服务
  5. premiere pr 把切开的视频合并起来
  6. linux shell 去掉 文本换行符
  7. node.js express项目搭建
  8. tcp时间戳 引起的网站不能访问
  9. goland 远程调试 golang
  10. shell中获取单个文件大小