Django--filter(**kwargs)

Posted echo-o

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django--filter(**kwargs)相关的知识,希望对你有一定的参考价值。

Django--filter(**kwargs)-exclude(**kwargs)


 filter()

说明:

  1. 数据的过滤
  2. 返回Queryset包含与给定查找参数匹配的对象。这里需要特别注意的地方就是返回的是一个对象,并且当符合条件是多个的时候可以对其进行遍历。

 实例测试:

首先是我们的模型类:

技术分享图片
from django.db import models

# Create your models here.

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=200)
    email = models.EmailField()

    def __str__(self):
        return self.name

class Entry(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField() # 发表时间
    mod_date = models.DateField() # 更新时间
    authors = models.ManyToManyField(Author)
    n_comments = models.IntegerField()
    n_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    def __str__(self):
        return self.headline
模型类

对数据库的数据进行添加:

技术分享图片
mysql> 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.07 sec)

mysql> mysql> select * from queryset_demo_author;
+----+-------+---------------+
| id | name  | email         |
+----+-------+---------------+
|  1 | Tom   | [email protected]   |
|  2 | Jone  | [email protected]  |
|  3 | Kevin | [email protected] |
|  4 | Joe   |               |
|  5 | John  |               |
|  6 | Paul  |               |
|  7 | Tom   | [email protected]    |
|  8 | Tom   | [email protected]    |
+----+-------+---------------+
8 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)

mysql> select * from queryset_demo_entry_authors;
+----+----------+-----------+
| id | entry_id | author_id |
+----+----------+-----------+
|  1 |        1 |         2 |
|  2 |        1 |         4 |
|  3 |        1 |         5 |
|  4 |        1 |         6 |
+----+----------+-----------+
4 rows in set (0.00 sec)
数据库的数据进行添加

获取在2017年发布的博客:

>>> Entry.objects.filter(pub_date__year=2017) #这里注意双下划线的用法
<QuerySet [<Entry: python-2017>, <Entry: python-2017>]>
# 使用manage的方式进行查询 返回的是一个查询集合该查询集合可以进行遍历和切片
>>> Entry.objects.all().filter(pub_date__year=2017)
<QuerySet [<Entry: python-2017>, <Entry: python-2017>]>

 exclude()

说明:

  1. 数据过滤,和filter基本上有相同的功能,但是需要注意的一点就是他是返回不匹配的结果。

返回不是2017年发布的博客内容:

>>> Entry.objects.all().exclude(pub_date__year=2017)

<QuerySet [<Entry: python>, <Entry: python>, <Entry: python-2015>, <Entry: python-2014>, <Entry: python-4>]>
>>> Entry.objects.exclude(pub_date__year=2017)

<QuerySet [<Entry: python>, <Entry: python>, <Entry: python-2015>, <Entry: python-2014>, <Entry: python-4>]>

结合数据库中的数据

 串联的使用对数据进行过滤:

>>> import datetime
>>>Entry.objects.filter(headline__startswith="python").exclude(pub_date__gte=datetime.date.today()).filter(pub_date__gte=datetime.date(2005, 1, 30))# __startswith 表示以什么开头
# 返回的查询集
<QuerySet [<Entry: python>, <Entry: python>, <Entry: python-2017>, <Entry: python-2017>, <Entry: python-2015>, <Entry: python-2014>, <Entry: python-4>]>

 QuerySet的一些特性:

  1.各自独立,就比如上面中的例子串联的使用其中的每一个filter()都是一个独立的QuerySet对象。相互之间没有直接的关系,相互之间没有影响,可以存储,可以使用,可以重用。

  2.延迟加载,并不是每一次调用filter()方法就会去查询一次数据库,只有在真正需要数据的时候才会去查询数据库,比如:

>>> q = Entry.objects.filter(headline__startswith="What")
>>> q = q.filter(pub_date__lte=datetime.date.today())
>>> q = q.exclude(body_text__icontains="food")
>>> print(q) 

总之看这个例子看似是对数据库进行了三次查询。但是实际上只是最后一行才和数据库进行交互。

获取一个单独的对象get()

注意:get()和filter()在使用过程中是存在差异的。就是返回值的问题

  当我们查询的数据不存在的时候:

  • get() 会抛出异常 DoesNotExist 所以我们这里需要特别的注意。
技术分享图片
>>> Entry.objects.get(pk=100)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/lee/PycharmProjects/Djdemo/venv/lib/python3.5/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/lee/PycharmProjects/Djdemo/venv/lib/python3.5/site-packages/django/db/models/query.py", line 403, in get
    self.model._meta.object_name
queryset_demo.models.DoesNotExist: Entry matching query does not exist.
get() 异常
  • filter()在使用的过程中当我们过滤的条件不存在的时候,会返回<QuerySet [ ]>
技术分享图片
>>> Entry.objects.filter(pk=100)
<QuerySet []>
返回空查询集

QuerySet的切片:

返回前5个对象:

>>> data =  Entry.objects.all()[0:5]
>>> [d.id for d in data]
[1, 2, 3, 4, 5]  # 返回前5个对象

返回 6-10 个对象:

>>> data =  Entry.objects.all()[3:5]
>>> [d.id for d in data]
[4, 5]

注意:

  不支持负索引

>>> Entry.objects.all()[-1]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/lee/PycharmProjects/Djdemo/venv/lib/python3.5/site-packages/django/db/models/query.py", line 286, in __getitem__
    "Negative indexing is not supported."
AssertionError: Negative indexing is not supported.

带有步长的切片:

>>> Entry.objects.all()[0:5:2] # 使用步长 获取前五个数据 步长为2
[<Entry: python>, <Entry: python-2017>, <Entry: python-2015>]
>>> data =  Entry.objects.all()[0:5:2]

>>> [d.id for d in data] # 返回数据的id 
[1, 3, 5]

简单的过滤order_by():

>>> data =  Entry.objects.order_by(id)
>>> [d.id for d in data]
[1, 2, 3, 4, 5, 6, 7]


>>> data =  Entry.objects.order_by(-id)
>>> [d.id for d in data]
[7, 6, 5, 4, 3, 2, 1]

获取单个的对象使用简单的索引:

技术分享图片
>>> entry_obj = Entry.objects.order_by(-id)[0]
>>> entry_obj
<Entry: python-4>
>>> type(entry_obj)
<class queryset_demo.models.Entry>


>>> QuerySet_obj = Entry.objects.order_by(-id)[0:1]
>>> QuerySet_obj
<QuerySet [<Entry: python-4>]>
>>> type(QuerySet_obj)
<class django.db.models.query.QuerySet>

>>> QuerySet_obj = Entry.objects.order_by(-id)[0:1].get()
>>> QuerySet_obj
<Entry: python-4>
#上下等价
>>> Entry.objects.order_by(-id)[0]
<Entry: python-4>
两种方式获取同一个对象

 


以上是关于Django--filter(**kwargs)的主要内容,如果未能解决你的问题,请参考以下文章

Django:Filter()不返回任何东西

DJango filter_queryset

django filter查询不到报啥错

Django filter中contains 用法

Django(filter过滤器)

Django filter_horizo ntal过滤