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