25f44ac9ca05f60260f70c4225e42c1e.jpg
常用到的QuerySet的api接口

常用到的QuerySet的api接口-支持链式调用

支持链式调用的接口即返回Queryset的接口,具体如下。

  • al1接口。相当于SELECT . FROM table-name语句,用于查询所有数据。
  • filter接口。顾名思义,根据条件过滤数据,常用的条件基本上是字段等于、不等于、大于、小于。当然,还有其他的,比如能改成产生LIKE查询的:> Model.objects. filter (content-contains=”条件“)
  • exclude接口。同filter,只是相反的逻辑。
  • reverse接口。把QuerySet中的结果倒序排列。
  • distinet接口。用来进行去重查询,产生SELECT DISTINCT 这样的SQL查询。
  • none接口。返回空的QuerySet。

常用到的QuerySet的api接口-不支持链式调用

不支持链式调用的接口即返回值不是QuerySet的接口,具体如下。

  • get or create接口。根据条件查找,如果没查找到,就调用create创建。
  • update or create接口。同get _or create,只是用来做更新操作。
  • count接口。用于返回Queryset有多少条记录,相当于> SELECT COUNT(*) FROM table_name
  • create接口。用来直接创建一一个Model 对象,比如post = Post.objects.create (title=”一起学习Django实战吧”)。
  • get接口。比如> Post.objects.get (id=1)


用于查询id为1的文章:如果存在,则直接返回对应的Post实例;如果不存在,则抛出DoesNotExist异常。所以一般情况下,我们会这么用:```python try: post = Post.objects.get (id=1) except Post. DoesNotExist :

  1. #做异常情况处理
  1. - latest按口。用于这回最新的n系记录,但是需要在ModelMeta中定义: get_lacest-by = <用来排序的字段>
  2. - Dearliest接口。同上,返回最早的条记录。
  3. - first接口。从当前QuerySet 记录中获取第一条。
  4. - last接口。同上,获取最后-条。
  5. - exists接口。返回True或者False,在数据库层面执行SELECT (1) AS "a" FROM table_ name LIMIT 1的查询,如果只是需要判断QuerySet是否有数据,用这个接口是最合适的方式。不要用count或者len (queryset)这样的操作来判断是否存在。相反,如果可以预期接下来会用到QuerySet中的数据,可以考虑使用len (queryset)的方式来做判断,这样可以减少-次DB查询请求。
  6. - bulk_ create 接口。同create,用来批量创建记录。
  7. - in_ bulk 接口。批量查询,接收两个参数id list filed name 可以通过post.objects.in_ bulk([1, 2, 3])查询出id123的数据,返回结果是字典类型,字典类型的key为查询条件。返回结果示例: {1: <Post 实例1>,2: <Post 实例2>,3: <Post 实例3> }。
  8. - update接口。用来根据条件批量更新记录,比如: Post . objects . filter (owner_ name='the5fire') .update(title='测试更新')。
  9. - delete接口,是用来根据条件批量删除记录。需要注意的是,delete 都会触发Djangosignal
  10. - values接口,当我们用确知道只需要返回某 个字段的值,不需要Mold实侧时用它,用法如下> Post.objecte. EiItericategory. id=l).values('title‘)
  11. <a name="549d5e15"></a>
  12. #### 扩展信息
  13. [django官方的QuerySetAPI](https://docs.djangoproject.com/zh-hans/3.1/ref/models/querysets/#django.db.models.query.QuerySet.none)
  14. <a name="833d62d9"></a>
  15. ### Django QuerySet常用的字段查询
  16. contains就属于字段查询。
  17. - contains:包含,用来进行相似查询
  18. - icontains:同contains,只是忽略大小写
  19. - exact:精确匹配
  20. - iexact:同exact,忽略大小写
  21. - in:指定某个集合,比如Post.objects.filter(id__in=[1,2,3]),相当于SELECT * FROM blog_post WHERE IN (1,2,3)
  22. - gt:大于某值
  23. - gte:大于等于某值
  24. - lt:小于某值
  25. - lte:小于等于某值
  26. - startswith:以某个字符串开头,与contains类似,只是会产生LIKE
  27. - istartswith:同startswith,忽略大小写
  28. - endswith:以某个字符串结尾
  29. - iendswith:同endswith,忽略大小写
  30. - range:范围查询,多用于时间范围,如Post.objects.filter(created_time_range=('2020-06-01','2020-06-28'))
  31. <a name="d52c7511"></a>
  32. ### Django QuerySet用到的进阶查询
  33. > 当一般的查询语句已经无法满足我们的需求时,Django为我们提供了F和Q复杂查询语句。假设场景一:老板说对数据库中所有的商品,在原价格的基础上涨价10元,你该怎么做?场景二:我要查询一个名字叫xxx,年龄是18岁,或者名字是yyy,年龄是是19岁的人,你该怎么写你的ORM语句
  34. <a name="56882945"></a>
  35. #### F查询
  36. ---
  37. ```python
  38. from django.db.models import F
  39. from app01.models import Book
  40. Book.objects.update(price=F("price")+20) # 对于book表中每本书的价格都在原价格的基础上增加20元

就这样一条简单的语句就完成了对表中所有商品价格的更新,是不是很方便!如果没有F查询,你首先要获取原价格,再做一个算术运算,然后更新字段。F查询专门对对象中某列值的操作,不可使用__双下划线!

Q查询


Q查询可以组合使用 “&”, “|” 操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象,Q对象可以用 “~” 操作符放在前面表示否定,也可允许否定与不否定形式的组合。Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。

  1. from django.db.models import Q
  2. print(Book.objects.filter(Q(id=3))[0]) # 因为获取的结果是一个QuerySet,所以使用下标的方式获取结果
  3. print(Book.objects.filter(Q(id=3)|Q(title="Go"))[0]) # 查询id=3或者标题是“Go”的书
  4. print(Book.objects.filter(Q(price__gte=70)&Q(title__startswith="J"))) # 查询价格大于等于70并且标题是“J”开头的书
  5. print(Book.objects.filter(Q(title__startswith="J") & ~Q(id=3))) # 查询标题是“J”开头并且id不是3的书
  6. print(Book.objects.filter(Q(price=70)|Q(title="Python"), publication_date="2017-09-26")) # Q对象可以与关键字参数查询一起使用,必须把普通关键字查询放到Q对象查询的后面
  1. from django.db.models import Q
  2. con = Q()
  3. q1 = Q()
  4. q1.connector = "AND"
  5. q1.children.append(("email", "123@qq.com"))
  6. q1.children.append(("password", "abc123"))
  7. q2 = Q()
  8. q2.connector = "AND"
  9. q2.children.append(("username", "abc"))
  10. q2.children.append(("password", "xyz123"))
  11. con.add(q1, "OR")
  12. con.add(q2, "OR")
  13. obj = models.UserInfo.objects.filter(con).first()
  14. # 查询email=123@qq.com和password=abc123 或者 username=abc和password=xyz123的用户信息

上面的例子就是一个典型的复杂查询,通过将Q对象实例化来然后增加各个条件之间的关系,而且这种写法用在你不知道用户到底会传入多少个参数的时候很方便!

以上就是通过两个小例子对Q查询和F查询的应用做一个简单的记录,更多查询的用法和API可以查阅Django的官方文档:https://docs.djangoproject.com/zh-hans/3.1/topics/db/queries/

聚合查询

聚合查询是做数据分析的数据库基础。通常使用聚合函数完成聚合查询:
Mysql聚类函数
Count 计数
Sum 求和
Avg 求平均数
Max最大
Min最小
django也有相似的操作,通常django和聚类查询和order_by,group_by
在django当中排序查询是order_by,分组查询是annotate,分组查询通常写在查询的尾部。
Django聚类查询的例子

django-models-QuerySet - 图3

Django使用聚类方法,需要通过aggregate方法。

  1. from django.db.models import Sum,Count,Avg
  2. ret = models.Book.objects.all().aggregate(price=Sum('price'))