Django--filter(**kwargs)-exclude(**kwargs)
filter()
说明:
- 数据的过滤
- 返回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 | Tom@123.com | | 2 | Jone | jone@123.com | | 3 | Kevin | kevin@123.com | | 4 | Joe | | | 5 | John | | | 6 | Paul | | | 7 | Tom | Tom@456.qq | | 8 | Tom | 123@qq.com | +----+-------+---------------+ 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.
- 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>