04.Django ORM条件查询

查询操作

在ORM层面,查询条件都使用field+__+condition的方式来使用。

查询条件

exact:

精确的提供条件,在底层会被翻译成=

iexact

在底层会被翻译成LIKE

in:

可以直接指定指定某个字段的是否在某个集合中。示例代码如下:

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)
gt

某个field的值要大于给定的值,相当于sql中>,大于

gte

类似于get,相当于sql中>=,大于等于

lt

相当于sql中<,小于

lte

相当于sql中<=,小于等于

startwith

判断某个字段的值是否是以某个值开始的。大小写敏感,示例代码如下:

article = Article.objects.filter(title__startwith='hello')
# 上面的代码将翻译以下sql语句,意思就是提取标题以`hello`开头的文章
select ...where title like "hello%"
istartwith

类似于startwith,但是大小写是不敏感的。

endswith

判断某个字段的值是否以某个值结束。大小写敏感。示例代码如下:

article = Aritcle.objects.filter(title_endswith="world")
# 以上代码的意思是提取title字段以world结尾的数据
select ... where title like "%world"
iendswith

类似于iendswith,但是大小写是不敏感的。

range

判断某个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

针对某些datedatetime类型的字段;可以指定date范围

article = Aritcle.objects.filter(pub_date__date=date(2019,4,19))
# 以上代码的意思是查找时间为2019/4/19这一天发表的文章
year

根据年份进行查找,示例代码如下:

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'
month

同year,根据月份进行查找。

day

同year,根据日期进行查找。

week_day

同year,根据星期几进行查询。1表示星期天,7表示星期六,2-6代表星期一到星期五。

time

根据时间进行查找。示例代码如下:

article = Article.objects.filter(pub_date__time=datetime.time(12,12,12)
# 以上代码代表获取每一天中12点12分12秒发表的所有文章
isnull

根据值是否为空进行查找,示例代码如下:

article = Article.objects.filter(pub_date__isnull=False)
# 以上的代码的意思是获取所有发布日期不为空的文章,将翻译如下sql语句:
select ... where pub_date is not null
regex和iregex

大小写敏感和大小写不敏感的正则表达式,示例代码如下:

article = Article.objects.filter(title__regex=r'^hello')
# 以上代码的意思是提取所有title以`hello`字符串开头的文章,将翻译成如下sql:
select ... where title regexp binary '^hello'

你可能感兴趣的:(Django)