在ORM层面,查询条件都使用field+__+condition
的方式来使用。
精确的提供条件,在底层会被翻译成
=
在底层会被翻译成
LIKE
可以直接指定指定某个字段的是否在某个集合中。示例代码如下:
def index1(request):
# 查找文章表中id为1,2,3的文章
article = Article.objects.filter(id__in=[1, 2, 3])
# 也可以通过其他的表的字段来判断是否在某个集合中
# 通过Category表查询Article表中id=1,2,3的数据
article = Category.objects.filter(article__id__in=[1, 2, 3])
print(article.query)
print(article)
如果要判断相关联的表的字段,那么也是通过__
来连接。并且在做反向引用的时候,不需要写modles_set
,直接使用模型的名字的小写化就可以。如果不想使用默认的形式,可以在外键定义的时候传递related_query_name
来指定反向应用的名字,示例代码如下:
# 文章表
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
category = models.ForeignKey("Category", on_delete=models.CASCADE, null=True,related_query_name='article')
class Meta:
db_table = "Article"
def __str__(self):
return "Article(id:%s,title:%s,content:%s)" % (self.id, self.title, self.content)
# 分类表
class Category(models.Model):
name = models.CharField(verbose_name='类别名称', max_length=100)
def __str__(self):
return "Category(id:%s, name:%s)" % (self.id, self.name)
#设定了`related_query_name='article'`就必须使用这个名称来做反向引用。
# 并且如果在做反向查询的时候,如果查询的字段就是模型的主键,那么可以省略掉这个字段,直接写出`article_in`就可以了,不需要这个`id`了。
# `in`不仅仅可以指定列表/元祖,还可以为`QuerySet`
articles = Article.objects.filter(title__icontains='中国')
categorys = Category.objects.filter(article__in=articles)
for category in categorys:
print(category)
某个field的值要大于给定的值,相当于sql中
>
,大于
类似于get,相当于sql中
>=
,大于等于
相当于sql中
<
,小于
相当于sql中
<=
,小于等于
判断某个字段的值是否是以某个值开始的。大小写敏感,示例代码如下:
article = Article.objects.filter(title__startwith='hello')
# 上面的代码将翻译以下sql语句,意思就是提取标题以`hello`开头的文章
select ...where title like "hello%"
类似于
startwith
,但是大小写是不敏感的。
判断某个字段的值是否以某个值结束。大小写敏感。示例代码如下:
article = Aritcle.objects.filter(title_endswith="world")
# 以上代码的意思是提取title字段以world结尾的数据
select ... where title like "%world"
类似于
iendswith
,但是大小写是不敏感的。
判断某个field的值是否在给定的区间中。示例代码如下:
from django.utils.timezone import make_aware
from datetime import datetime
start_date = make_aware(datetime(year=2019, month=4, day=10))
end_date = make_aware(datetime(year=2019, month=5, day=10))
article = Article.objects.filter(title__range=(start_date, end_date))
# 以上代码的意思提取title时间在2019/4/10到2019/5/10的文章,原生sql语句如下
select ... from article where title between '2019-4-10' and '2019-5-10'
针对某些
date
或datetime
类型的字段;可以指定date范围
article = Aritcle.objects.filter(pub_date__date=date(2019,4,19))
# 以上代码的意思是查找时间为2019/4/19这一天发表的文章
根据年份进行查找,示例代码如下:
article = Article.objects.filter(pub_date__year=2019)
article = Article.objects.filter(pub_date__year__gte=2018)
# 以上的代码将翻译成如下sql语句:
select ... where pub_date between '2019-01-01' and '2019-12-31'
select ... where pub_date >= '2018-01-01'
同year,根据月份进行查找。
同year,根据日期进行查找。
同year,根据星期几进行查询。1表示星期天,7表示星期六,2-6代表星期一到星期五。
根据时间进行查找。示例代码如下:
article = Article.objects.filter(pub_date__time=datetime.time(12,12,12)
# 以上代码代表获取每一天中12点12分12秒发表的所有文章
根据值是否为空进行查找,示例代码如下:
article = Article.objects.filter(pub_date__isnull=False)
# 以上的代码的意思是获取所有发布日期不为空的文章,将翻译如下sql语句:
select ... where pub_date is not null
大小写敏感和大小写不敏感的正则表达式,示例代码如下:
article = Article.objects.filter(title__regex=r'^hello')
# 以上代码的意思是提取所有title以`hello`字符串开头的文章,将翻译成如下sql:
select ... where title regexp binary '^hello'