Django--filter()-字段查找(双下划线的使用详解)


在了解django中的字段查找的同时,让我们先熟悉一下比较符:

大于--gt-(greater than)  小于--lt-(less than)  等于--eq-(equal)  大于等于--gte  小于等于--lte

  1. >>> from queryset_demo.models import Blog,Author,Entry
  2. >>> entry = Entry.objects.filter(pub_date__lte='2017-01-01')
  3. >>> entry
  4. <QuerySet [<Entry: python-2015>, <Entry: python-2014>, <Entry: python-4>]>
  5. >>> [d.id for d in entry] # 返回数据的id
  6. [5, 6, 7]

对应的sql语句为

  1. mysql> select * from queryset_demo_entry
  2. -> ;
  3. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  4. | id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
  5. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  6. | 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
  7. | 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
  8. | 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
  9. | 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
  10. | 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
  11. | 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
  12. | 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
  13. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  14. 7 rows in set (0.00 sec)
  15.  
  16. mysql> select * from queryset_demo_entry where pub_date<2017-01-01;
  17. Empty set, 1 warning (0.00 sec)
  18.  
  19. mysql> select * from queryset_demo_entry where pub_date<'2017-01-01';
  20. +----+-------------+-----------+------------+------------+------------+-------------+--------+---------+
  21. | id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
  22. +----+-------------+-----------+------------+------------+------------+-------------+--------+---------+
  23. | 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
  24. | 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
  25. | 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
  26. +----+-------------+-----------+------------+------------+------------+-------------+--------+---------+
  27. 3 rows in set (0.00 sec)

对应的sql语句

对外键ForeignKey的字段查找,同时也是一个特殊的地方就是可以通过单下划线

  1. >>> entry
  2. <QuerySet [<Entry: python>, <Entry: python-4>]>
  3. >>> type(entry)
  4. <class 'django.db.models.query.QuerySet'>
  5. >>> [d.id for d in entry]
  6. [1, 7]

sql

  1. mysql> select * from queryset_demo_entry
  2. -> ;
  3. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  4. | id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
  5. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  6. | 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
  7. | 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
  8. | 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
  9. | 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
  10. | 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
  11. | 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
  12. | 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
  13. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  14. 7 rows in set (0.00 sec)

精确查找exact

  1. >>> entry=Entry.objects.get(body_text__exact="This is a demo")
  2. >>> entry.id
  3. 1
  4.  
  5. >>> entry=Entry.objects.get(body_text="This is a demo")
  6. >>> entry.id
  7. 1

sql

  1. mysql> select * from queryset_demo_entry
  2. -> ;
  3. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  4. | id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
  5. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  6. | 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
  7. | 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
  8. | 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
  9. | 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
  10. | 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
  11. | 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
  12. | 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
  13. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  14. 7 rows in set (0.00 sec)
  15.  
  16. mysql> select * from queryset_demo_entry where body_text ='This is a demo';
  17. +----+----------+----------------+------------+------------+------------+-------------+--------+---------+
  18. | id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
  19. +----+----------+----------------+------------+------------+------------+-------------+--------+---------+
  20. | 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
  21. +----+----------+----------------+------------+------------+------------+-------------+--------+---------+
  22. 1 row in set (0.00 sec)

跨表查询

  1. >>> Entry.objects.filter(blog__name='blog_3')
  2. <QuerySet [<Entry: python>, <Entry: python-4>]>
  3. >>> entry=Entry.objects.filter(blog__name='blog_3')
  4. >>> [d.id for d in entry]
  5. [1, 7]

sql

  1. mysql> select * from queryset_demo_blog;
  2. +----+-----------------+------------------------------+
  3. | id | name | tagline |
  4. +----+-----------------+------------------------------+
  5. | 1 | change_new_name | All the latest Beatles news. |
  6. | 2 | create_test | This is the wayof create |
  7. | 3 | Cheddar Talk | One to Many test |
  8. | 4 | blog_3 | this is a test |
  9. +----+-----------------+------------------------------+
  10. 4 rows in set (0.00 sec)
  11.  
  12. mysql> select * from queryset_demo_entry
  13. -> ;
  14. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  15. | id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
  16. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  17. | 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
  18. | 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
  19. | 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
  20. | 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
  21. | 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
  22. | 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
  23. | 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
  24. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  25. 7 rows in set (0.00 sec)

反向查询

通过blog表进行查询

它也可以倒退。要引用“反向”关系,只需使用模型的小写名称即可。

这个例子检索所有Blog具有至少一个对象Entry ,其headline包含'Lennon'

  1. >>> from queryset_demo.models import *
  2. >>> blog = Blog.objects.filter(entry__body_text__contains='dj')
  3. >>> blog
  4. <QuerySet [<Blog: create_test>, <Blog: Cheddar Talk>, <Blog: change_new_name>]>
  5. >>> [d.id for d in blog]
  6. [2, 3, 1]
  7. >>>

跨越多值关系

使用下划线查找多值得关系

  1. >>> blog = Blog.objects.filter(entry__body_text__contains='dj')
  2. >>> blog
  3. <QuerySet [<Blog: create_test>, <Blog: Cheddar Talk>, <Blog: change_new_name>]>
  4. >>> [d.id for d in blog]
  5. [2, 3, 1]
  6. >>> blog = Blog.objects.filter(entry__body_text__contains='dj',entry__pub_date__year=2017)
  7. >>> [d.id for d in blog]
  8. [3, 1]
  9. >>> blog = Blog.objects.filter(entry__body_text__contains='dj').filter(entry__pub_date__year=2017)
  10. >>> blog_2 = Blog.objects.filter(entry__body_text__contains='dj').filter(entry__pub_date__year=2017)
  11. >>> blog_2
  12. <QuerySet [<Blog: Cheddar Talk>, <Blog: change_new_name>]>
  13. >>> blog
  14. <QuerySet [<Blog: Cheddar Talk>, <Blog: change_new_name>]>
  15. >>>

英文:

  Suppose there is only one blog that had both entries containing “Lennon” and entries from 2008, but that none of the entries from 2008 contained “Lennon”. The first query would not return any blogs, but the   second query would return that one blog.

  In the second example, the first filter restricts the queryset to all those blogs linked to entries with “Lennon” in the headline. The second filter restricts the set of blogs further to those that are also linked to entries that were published in 2008. The entries selected by the second filter may or may not be the same as the entries in the first filter. We are filtering the Blog items with each filter statement, not the Entry items.

理解:

数据库进行数据的添加

  1. mysql> mysql> select * from queryset_demo_entry;
  2. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  3. | id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
  4. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  5. | 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
  6. | 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
  7. | 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
  8. | 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
  9. | 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
  10. | 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
  11. | 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
  12. | 8 | demo | demo | 2017-06-16 | 2017-05-16 | 33 | 33 | 5 | 2 |
  13. | 9 | demo2 | zzddxx | 2017-02-16 | 2017-02-04 | 44 | 33 | 22 | 3 |
  14. +----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
  15. 9 rows in set (0.00 sec)
  16.  
  17. mysql> select * from queryset_demo_blog;
  18. +----+-----------------+------------------------------+
  19. | id | name | tagline |
  20. +----+-----------------+------------------------------+
  21. | 1 | change_new_name | All the latest Beatles news. |
  22. | 2 | create_test | This is the wayof create |
  23. | 3 | Cheddar Talk | One to Many test |
  24. | 4 | blog_3 | this is a test |
  25. +----+-----------------+------------------------------+
  26. 4 rows in set (0.01 sec)

shell进行测试

  1. >>> blog = Blog.objects.filter(entry__body_text__contains='dj',entry__pub_date__year=2017)
  2. >>> blog
  3. <QuerySet [<Blog: Cheddar Talk>, <Blog: change_new_name>]>
  4. >>>
  5. >>>
  6. >>> blog_2 = Blog.objects.filter(entry__body_text__contains='dj').filter(entry__pub_date__year=2017)
  7. >>> blog_2
  8. <QuerySet [<Blog: create_test>, <Blog: Cheddar Talk>, <Blog: Cheddar Talk>, <Blog: change_new_name>]>
  9. >>> [d.id for d in blog]
  10. [3, 1]
  11. >>> [d.id for d in blog_2]
  12. [2, 3, 3, 1]

Django--filter()-字段查找(双下划线的使用详解)的更多相关文章

  1. Django 数据库查询集合(双下划线连表操作)

    Django是一款优秀的web框架,有着自己的ORM数据库模型.在项目中一直使用django数据库,写一篇文章专门记录一下数据库操作.略写django工程创建过程,详写查询过程.可以和sqlalche ...

  2. Django基础(5) ----基于双下划线的跨表查询,聚合查询,分组查询,F查询,Q查询

    一.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接模型(mode ...

  3. Django Mysql数据库-基于双下划线的跨表查询

    一.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接模型(mode ...

  4. django后台使用MySQL情况下的事务控制详解

    写在前面: 默认情况下django会把autocommit设置为“1”也就是说所针对数据库的每一次操作都会被做成“单独”的一个事务:这样的处理好处就在于它方便, 在编程的时候可以少写一些代码,比如我们 ...

  5. Django ORM字段类型 单表增删改查 万能的双下划线

    1.ORM三种模型 模型之间的三种关系:一对一,一对多,多对多. 一对一:实质就是在主外键(author_id就是foreign key)的关系基础上,给外键加了一个UNIQUE=True的属性: 一 ...

  6. django基础之day04,必知必会13条,双下划线查询,字段增删改查,对象的跨表查询,双下划线的跨表查询

    from django.test import TestCase # Create your tests here. import os import sys if __name__ == " ...

  7. Django框架之第六篇(模型层)--单表查询和必知必会13条、单表查询之双下划线、Django ORM常用字段和参数、关系字段

    单表查询 补充一个知识点:在models.py建表是 create_time = models.DateField() 关键字参数: 1.auto_now:每次操作数据,都会自动刷新当前操作的时间 2 ...

  8. Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询

    Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...

  9. django models的点查询/跨表查询/双下划线查询

    django models 在日常的编程中,我们需要建立数据库模型 而往往会用到表与表之间的关系,这就比单表取数据要复杂一些 在多表之间发生关系的情形下,我们如何利用models提供的API的特性获得 ...

随机推荐

  1. SSM-网站前台博客系统制作(2)---完善版Google的Kaptcha

    前提: 在上一篇文章中,可以加入基本的验证码,但是很呆板,验证码也无法传输到Controller进行处理,然后现在改正了一下,可以刷新验证码,然后和登录名,密码一起提交过去, 弄了一下午和晚上,QAQ ...

  2. Windows环境下利用anaconda3安装python版本的Xgboost

    网上有各种不同安装Xgboost的教程,但是有些教程对于一个新手来说,照着做安装成功是很困难的.本人也是新手,第一次安装Xgboost的时候,照着某个教程做,结果总是安装不上,甚至想到要放弃.后来经一 ...

  3. PHP 获取当前访问的完整URL

    代码如下: <?php // php 获取当前访问的完整url function GetCurUrl() { $url = 'http://'; if(isset($_SERVER['HTTPS ...

  4. 【VS2019】F12跳转到源码

    1.工具->选项 2.文本编辑器->C#->高级->勾选支持导航到反编译源码 3.关闭浏览器不停止项目

  5. CART回归树

    决策树算法原理(ID3,C4.5) 决策树算法原理(CART分类树) 决策树的剪枝 CART回归树模型表达式: 其中,数据空间被划分为R1~Rm单元,每个单元有一个固定的输出值Cm.这样可以计算模型输 ...

  6. APScheduler——定时任务框架

    https://www.cnblogs.com/luxiaojun/p/6567132.html

  7. Python自学:第三章 使用del语句删除元素

    motorcycles = ["honda", "yamaha", "suzuki"] print(motorcycles) del mot ...

  8. Java核心技术卷一 · 笔记(1)

    目录 1.java的关键术语 2.==和equals 3.空串与 Null 串 4.构建字符串 5.封装 6.对象的三个主要特性 7.依赖(dependence).聚合(aggregation).继承 ...

  9. 找到多个与名为“Home”的控制器匹配的类型

    “/”应用程序中的服务器错误. 找到多个与名为“Home”的控制器匹配的类型.如果为此请求(“{controller}/{action}/{id}”)提供服务的路由没有指定命名空间以搜索与此请求相匹配 ...

  10. windows系统下安装rabbitmq教程

    1.简介 安装rabbitmq需要下载软件Erlang语言开发包和RabbitMQ文件包.文件最新下载地址如下: Erlang: https://www.erlang.org/ RabbitMQ: h ...