数据查询时数据库操作中的重要技术。查询一般是通过filter
、exclude
以及get
三个方法实现的。而在ORM
层面,查询条件都是使用field
+__
+condition(查询条件)
的方式来使用的。
常用的过滤器:
filter
:返回符合条件的所有数据(多条数据);exclude
:返回不符合条件的所有数据(多条数据);get
:返回符合条件的第一条数据(单条数据)。
以下介绍常用的查询条件。
文章目录
1.exact
使用精确的=
进行查找。如果提供的是一个None
值,则在sql
层面被解释为NULL
。
示例代码:
article = Article.objects.get(id__exact=14)
article = Article.objects.get(id__exact=None)
翻译为:
select ... from article where id = 14
select ... from article where id IS NULL;
也可简单地使用
=
。
2.iexact
在sql
层面使用like
进行查找。
示例代码:
article = Article.objects.filter(title__iexact='abc')
翻译为:
select ... from article where title like 'abc';
3.contains
判断某个字段是否包含了某数据,大小写敏感。
示例代码:
articles = Article.objects.filter(title__contains="ab")
翻译为:
select ... where title like binary '%ab%';
在使用contains
的时候,翻译成的sql
语句左右两边是有百分号的,意味着使用的是模糊查询。而exact
翻译的sql
语句左右两边是没有百分号的,意味着使用的是精确查询。
4.icontains
大小写不敏感的包含匹配查询。
示例代码:
articles = Article.objects.filter(title__icontains='ab')
翻译为:
select ... where title like '%ab%';
5.in
查询值在给定容器中的数据。容器可以为list
、tuple
或者任何一个可迭代的对象,包括QuerySet
对象。
示例代码:
articles = Article.objects.filter(id__in=[1,2,3])
翻译为:
select ... where id in (1,2,3)
当然也可以传入一个QuerySet
对象,示例代码:
inner_qs = Article.objects.filter(title__contains='abc')
categories = Category.objects.filter(article__in=inner_qs)
以上代码的意思是获取文章标题含有字符串abc
的文章的所有分类,翻译为:
select ... from category where article.id in (select id from article where title like '%abc%');
6.gt
筛选出其值大于给定值的数据(geater)。
示例代码:
articles = Article.objects.filter(id__gt=4)
将所有id
大于4的文章都找出来,翻译为:
select ... where id>4;
7.gte
类似于gt
,其含义为大于等于。
8.lt
类似于get
,是小于。
9.lte
·类似于lt
,是小于等于。
10.startwith
筛选出以某个值开始的字段,大小写敏感。
示例代码:
articles = Article.objects,filter(title__startwith='ab')
即提取所有标题以字符串ab
开头的文章,翻译为:
select ... where title like 'hello%';
11.istartwith
类似于startwith
,但是大小写不敏感。
12.endswith
判筛选出以某个值结尾的数据,大小写敏感。
示例代码:
articles = Article.objects.filter(title__endswith='cd')
翻译为:
select ... where title like '%cd';
13.iendswith
类似于endswith
,但大小写敏感。
14.range
筛选出值在给定区间内的数据。
示例代码:
from django.utils.times.timezone import make_aware
from datetim import datetime
start_date = make_aware(datetime(year=2018,moth=1,day=1))
end_date = make_aware(datetime(year=2018,month=3,day=29,hour=16))
articles = Article.objects.filter(publish_time__range=(start_date,end_date))
以上的代码获取所有发表时间在2018/1/1
到2018/12/12/16:00
之间的文章,可翻译为:
select ... from article where publish_time between '2018-01-01' and `2018-12-12`
需注意的是,以上数据的提取,不会包含上界的值。且若在setting.py
中指定了USE_TZ=True
,且设置TIME_ZONE='Asia.Shanghai'
,则在提取数据时要使用django.utils.timezone.make_aware
先将datetime.datetime
从naive
时间转换为aware
时间。make_aware
会将指定的时间转换为TIME_ZONE
中指定时区的时间。
15.isnull
筛选出值为空或非空的数据。
示例代码:
articles = Article.objects.filter(publish_time__isnull=False)
翻译为:
select ... where publish_time is not null;
16.regex与iregex
分别为大小写敏感与大小写不敏感的正则表达式。
示例代码:
articles = Article.objects.filter(title__regex=r'^abc')
17.时间相关
date
、year
、month
、day
、week_day
y与time
等。
根据关联表的查询
假如有两个模型,一个为Article
,一个为Author
:
class Author(models.Model):
name = models.CharField(max_length=20)
password = models.PasswordField()
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey(Author,on_delete=models.CASCADE)
则若此时想要获得写过文章标题中包含abc
的所有作者,则可以通过:
authors = Author.objects.filter(article__title__contains("abc"))