Django--filter()-字段查找(双下划线的使用详解)
Django--filter()-字段查找(双下划线的使用详解)
在了解django中的字段查找的同时,让我们先熟悉一下比较符:
大于--gt-(greater than) 小于--lt-(less than) 等于--eq-(equal) 大于等于--gte 小于等于--lte
>>> from queryset_demo.models import Blog,Author,Entry
>>> entry = Entry.objects.filter(pub_date__lte='2017-01-01')
>>> entry
<QuerySet [<Entry: python-2015>, <Entry: python-2014>, <Entry: python-4>]>
>>> [d.id for d in entry] # 返回数据的id
[5, 6, 7]
对应的sql语句为
mysql> select * from queryset_demo_entry
-> ;
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
| 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
| 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
| 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
| 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
| 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
| 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
7 rows in set (0.00 sec) mysql> select * from queryset_demo_entry where pub_date<2017-01-01;
Empty set, 1 warning (0.00 sec) mysql> select * from queryset_demo_entry where pub_date<'2017-01-01';
+----+-------------+-----------+------------+------------+------------+-------------+--------+---------+
| id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
+----+-------------+-----------+------------+------------+------------+-------------+--------+---------+
| 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
| 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
| 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
+----+-------------+-----------+------------+------------+------------+-------------+--------+---------+
3 rows in set (0.00 sec)
对应的sql语句
对外键ForeignKey的字段查找,同时也是一个特殊的地方就是可以通过单下划线
>>> entry
<QuerySet [<Entry: python>, <Entry: python-4>]>
>>> type(entry)
<class 'django.db.models.query.QuerySet'>
>>> [d.id for d in entry]
[1, 7]
sql
mysql> select * from queryset_demo_entry
-> ;
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
| 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
| 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
| 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
| 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
| 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
| 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
7 rows in set (0.00 sec)
精确查找exact
>>> entry=Entry.objects.get(body_text__exact="This is a demo")
>>> entry.id
1 >>> entry=Entry.objects.get(body_text="This is a demo")
>>> entry.id
1
sql
mysql> select * from queryset_demo_entry
-> ;
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
| 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
| 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
| 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
| 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
| 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
| 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
7 rows in set (0.00 sec) mysql> select * from queryset_demo_entry where body_text ='This is a demo';
+----+----------+----------------+------------+------------+------------+-------------+--------+---------+
| id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
+----+----------+----------------+------------+------------+------------+-------------+--------+---------+
| 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
+----+----------+----------------+------------+------------+------------+-------------+--------+---------+
1 row in set (0.00 sec)
跨表查询
>>> Entry.objects.filter(blog__name='blog_3')
<QuerySet [<Entry: python>, <Entry: python-4>]>
>>> entry=Entry.objects.filter(blog__name='blog_3')
>>> [d.id for d in entry]
[1, 7]
sql
mysql> select * from queryset_demo_blog;
+----+-----------------+------------------------------+
| id | name | tagline |
+----+-----------------+------------------------------+
| 1 | change_new_name | All the latest Beatles news. |
| 2 | create_test | This is the wayof create |
| 3 | Cheddar Talk | One to Many test |
| 4 | blog_3 | this is a test |
+----+-----------------+------------------------------+
4 rows in set (0.00 sec) mysql> select * from queryset_demo_entry
-> ;
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
| 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
| 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
| 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
| 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
| 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
| 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
7 rows in set (0.00 sec)
反向查询
通过blog表进行查询
它也可以倒退。要引用“反向”关系,只需使用模型的小写名称即可。
这个例子检索所有Blog具有至少一个对象Entry ,其headline包含'Lennon':
>>> from queryset_demo.models import *
>>> blog = Blog.objects.filter(entry__body_text__contains='dj')
>>> blog
<QuerySet [<Blog: create_test>, <Blog: Cheddar Talk>, <Blog: change_new_name>]>
>>> [d.id for d in blog]
[2, 3, 1]
>>>
跨越多值关系
使用下划线查找多值得关系
>>> blog = Blog.objects.filter(entry__body_text__contains='dj')
>>> blog
<QuerySet [<Blog: create_test>, <Blog: Cheddar Talk>, <Blog: change_new_name>]>
>>> [d.id for d in blog]
[2, 3, 1]
>>> blog = Blog.objects.filter(entry__body_text__contains='dj',entry__pub_date__year=2017)
>>> [d.id for d in blog]
[3, 1]
>>> blog = Blog.objects.filter(entry__body_text__contains='dj').filter(entry__pub_date__year=2017)
>>> blog_2 = Blog.objects.filter(entry__body_text__contains='dj').filter(entry__pub_date__year=2017)
>>> blog_2
<QuerySet [<Blog: Cheddar Talk>, <Blog: change_new_name>]>
>>> blog
<QuerySet [<Blog: Cheddar Talk>, <Blog: change_new_name>]>
>>>
英文:
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.
理解:
数据库进行数据的添加
mysql> mysql> select * from queryset_demo_entry;
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| id | headline | body_text | pub_date | mod_date | n_comments | n_pingbacks | rating | blog_id |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
| 1 | python | This is a demo | 2018-07-11 | 2018-07-14 | 10 | 29 | 23 | 4 |
| 2 | python | django | 2018-07-12 | 2018-07-28 | 2 | 2 | 2 | 2 |
| 3 | python-2017 | djagoddd | 2017-06-01 | 2017-08-14 | 55 | 676 | 88 | 3 |
| 4 | python-2017 | django-ll | 2017-03-14 | 2017-07-14 | 22 | 33 | 44 | 1 |
| 5 | python-2015 | ddd | 2015-07-14 | 2015-07-14 | 33 | 33 | 33 | 1 |
| 6 | python-2014 | ddd | 2014-07-14 | 2014-07-14 | 22 | 33 | 33 | 3 |
| 7 | python-4 | ddd | 2014-07-14 | 2018-07-04 | 66 | 66 | 66 | 4 |
| 8 | demo | demo | 2017-06-16 | 2017-05-16 | 33 | 33 | 5 | 2 |
| 9 | demo2 | zzddxx | 2017-02-16 | 2017-02-04 | 44 | 33 | 22 | 3 |
+----+-------------+----------------+------------+------------+------------+-------------+--------+---------+
9 rows in set (0.00 sec) mysql> select * from queryset_demo_blog;
+----+-----------------+------------------------------+
| id | name | tagline |
+----+-----------------+------------------------------+
| 1 | change_new_name | All the latest Beatles news. |
| 2 | create_test | This is the wayof create |
| 3 | Cheddar Talk | One to Many test |
| 4 | blog_3 | this is a test |
+----+-----------------+------------------------------+
4 rows in set (0.01 sec)
shell进行测试
>>> blog = Blog.objects.filter(entry__body_text__contains='dj',entry__pub_date__year=2017)
>>> blog
<QuerySet [<Blog: Cheddar Talk>, <Blog: change_new_name>]>
>>>
>>>
>>> blog_2 = Blog.objects.filter(entry__body_text__contains='dj').filter(entry__pub_date__year=2017)
>>> blog_2
<QuerySet [<Blog: create_test>, <Blog: Cheddar Talk>, <Blog: Cheddar Talk>, <Blog: change_new_name>]>
>>> [d.id for d in blog]
[3, 1]
>>> [d.id for d in blog_2]
[2, 3, 3, 1]
Django--filter()-字段查找(双下划线的使用详解)的更多相关文章
- Django 数据库查询集合(双下划线连表操作)
Django是一款优秀的web框架,有着自己的ORM数据库模型.在项目中一直使用django数据库,写一篇文章专门记录一下数据库操作.略写django工程创建过程,详写查询过程.可以和sqlalche ...
- Django基础(5) ----基于双下划线的跨表查询,聚合查询,分组查询,F查询,Q查询
一.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接模型(mode ...
- Django Mysql数据库-基于双下划线的跨表查询
一.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接模型(mode ...
- django后台使用MySQL情况下的事务控制详解
写在前面: 默认情况下django会把autocommit设置为“1”也就是说所针对数据库的每一次操作都会被做成“单独”的一个事务:这样的处理好处就在于它方便, 在编程的时候可以少写一些代码,比如我们 ...
- Django ORM字段类型 单表增删改查 万能的双下划线
1.ORM三种模型 模型之间的三种关系:一对一,一对多,多对多. 一对一:实质就是在主外键(author_id就是foreign key)的关系基础上,给外键加了一个UNIQUE=True的属性: 一 ...
- django基础之day04,必知必会13条,双下划线查询,字段增删改查,对象的跨表查询,双下划线的跨表查询
from django.test import TestCase # Create your tests here. import os import sys if __name__ == " ...
- Django框架之第六篇(模型层)--单表查询和必知必会13条、单表查询之双下划线、Django ORM常用字段和参数、关系字段
单表查询 补充一个知识点:在models.py建表是 create_time = models.DateField() 关键字参数: 1.auto_now:每次操作数据,都会自动刷新当前操作的时间 2 ...
- Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询
Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...
- django models的点查询/跨表查询/双下划线查询
django models 在日常的编程中,我们需要建立数据库模型 而往往会用到表与表之间的关系,这就比单表取数据要复杂一些 在多表之间发生关系的情形下,我们如何利用models提供的API的特性获得 ...
随机推荐
- [c/c++] programming之路(29)、阶段答疑
一.指针不等于地址 指针不仅有地址,还有类型,是一个存储了地址的变量,可以改变指向:而地址是一个常量 #include<stdio.h> #include<stdlib.h> ...
- 殊途同归 - Church-Rosser and Consistency of Evaluation
在"解释语言的语言"中提到,设计一个新的语言,仅仅是使用meta-language给出其描述是不够的,我们还需要去验证一些性质. 考虑一下我们在"解释语言 ...
- unittest同时支持参数化和生成html报告
最近在用python3.6+unittest+requests做自动化接口测试.发现一个问题,unittest中使用第3方插件parameterized进行参数化,再生成html报告时,运行就会失败. ...
- shell 的多进程
例子 #!/bin/bash temp_fifo_file=$$.info #以当前进程号,为临时管道取名 mkfifo $temp_fifo_file #创建临时管道 exec <>$t ...
- RabbitMQ跟Redis做消息队列的区别
区别 https://www.zhihu.com/question/20795043 https://blog.csdn.net/dd18709200301/article/details/79077 ...
- leecode第二百一十七题(存在重复元素)
class Solution { public: bool containsDuplicate(vector<int>& nums) { set<int> s; for ...
- lua 5.3.5 安装/初体验
安装 官网http://www.lua.org/start.html 参考 https://blog.csdn.net/qq_23954569/article/details/70879672 cd ...
- 实用的shell脚本面试题和答案
1. 写一个shell脚本来得到当前的日期,时间,用户名和当前工作目录. 答案 : 输出用户名,当前日期和时间,以及当前工作目录的命令就是logname,date,who i am和pwd. 现在,创 ...
- jmeter的安装和配置
jmeter环境配置 Java 8 安装 正常安装,一路默认就好,记住安装路径,配置环境变量时用得到.默认安装路径:C:\Program Files\Java\jdk1.8.0_91. 安装好之后会有 ...
- 【Mac】Mac中如何将相同后缀的所有文件设置指定软件打开
操作步骤: 以settings.xml文件为例 1.首先选中该文件,鼠标右键打开功能列表,选则查看文件信息 2.在文件信息中,进行相关设置