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

本文深入探讨了Django框架中ORM操作的高级用法,包括条件筛选、跨表查询、反向查询以及多值关系的查找技巧。通过具体实例展示了如何使用双下划线语法进行复杂的字段匹配和日期范围查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)
View Code

 

精确查找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)
View Code

 

 

跨表查询

>>> 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)
View Code

 

反向查询

通过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]

 

转载于:https://www.cnblogs.com/Echo-O/p/9311891.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值