django数据库操作-查01-基础条件查询

174 阅读3分钟

基础条件查询

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

在本指南(以及参考资料)中,我们将参考以下模型,

from django.db import models

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)
    number_of_comments = models.IntegerField()
    number_of_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    def __str__(self):
        return self.headline

1 基本查询

get查询单一结果,如果不存在会抛出模型类.DoesNotExist异常。

all查询多个结果。

count查询结果数量。

>>> Blog.objects.get(id=1)

>>> Blog.objects.all()

>>> Blog.objects.count()

2 过滤查询

  • filter过滤出多个结果,返回一个新的 QuerySet,包含的对象满足给定查询参数
  • exclude排除掉符合条件剩下的结果,返回一个新的 QuerySet,包含的对象  满足给定查询参数
  • get过滤单一结果

2.1 filter

要包含获取 2006 年的博客条目(entries blog)的 QuerySet,像这样使用 filter():

Entry.objects.filter(pub_date__year=2006)
Entry.objects.all().filter(pub_date__year=2006)

链式过滤器

精炼 QuerySet的结果本身还是一个 QuerySet,所以能串联精炼过程。例子:

>>> Entry.objects.filter(
...     headline__startswith='What'
... ).exclude(
...     pub_date__gte=datetime.date.today()
... ).filter(
...     pub_date__gte=datetime.date(2005, 1, 30)
... )    # (每个QuerySet是唯一的,是惰性的【执行最后面的】)

2.2 get

用 get() 检索单个对象

filter() 总是返回一个 QuerySet,即便只有一个对象满足查询条件 —— 这种情况下, QuerySet只包含了一个元素。

若你知道只会有一个对象满足查询条件,你可以在 Manager 上使用 get() 方法,它会直接返回这个对象:

>>> one_entry = Entry.objects.get(pk=1)

2.3 exclude

>>> q1 = Entry.objects.filter(headline__startswith="What")
>>> q2 = q1.exclude(pub_date__gte=datetime.date.today()) [惰性]

3 过滤条件的表达语法如下:

属性名称__比较运算符=值

# 属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线

1)相等

exact:表示判等。

例:查询编号为1的。

Blog.objects.filter(id__exact=1)
可简写为:
Bog.objects.filter(id=1)

iexact:不分大小写的匹配,查询语句:

```
>>> Blog.objects.get(name__iexact="beatles blog")
```

2)模糊查询

contains:是否包含。

说明:如果要包含%无需转义,直接写即可。

例:查询书名包含'传'的图书。

BookInfo.objects.filter(name__contains='传')
<QuerySet [<BookInfo: 射雕英雄传>]>

大小写不敏感的版本, icontains

startswith、endswith:以指定值开头或结尾。

>>> Blog.objects.filter(name__endswith='a')

以上运算符都区分大小写,在这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith.

3) 空查询

isnull:是否为null。

>>> Blog.objects.filter(name__isnull=True)

4) 范围查询

in:是否包含在范围内。

>>> Blog.objects.filter(id__in=[1,35])

5)比较查询

  • gt大于 (greater then)
  • gte大于等于 (greater then equal)
  • lt小于 (less then)
  • lte小于等于 (less then equal)

例:查询编号大于3的

Blog.objects.filter(id__gt=3)

不等于的运算符,使用exclude()过滤器。

例:查询编号不等于3的

>>> Blog.objects.exclude(id__gt=3)

6)日期查询

year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。

例:查询1980年发表的。

>>> Blog.objects.filter(pub_date__year=1980)

例:查询1990年1月1日后发表的。

>>> Blog.objects.filter(pub_date__gt='1990-1-1')

7)主键 (pk) 查询快捷方式

出于方便的目的,Django 提供了一种 pk 查询快捷方式, pk 表示主键 "primary key"。

示例 Blog 模型中,主键是 id 字段,所以这 3 个语句是等效的:

>>> Blog.objects.get(id__exact=14) # Explicit form
>>> Blog.objects.get(id=14) # __exact is implied
>>> Blog.objects.get(pk=14) # pk implies id__exact

pk 的使用并不仅限于 __exact 查询——任何的查询项都能接在 pk 后面,执行对模型主键的查询:

# Get blogs entries with id 1, 4 and 7
>>> Blog.objects.filter(pk__in=[1,4,7])

# Get all blog entries with id > 14
>>> Blog.objects.filter(pk__gt=14)

pk 查找也支持跨连接。例如,以下 3 个语句是等效的:

>>> Entry.objects.filter(blog__id__exact=3) # Explicit form
>>> Entry.objects.filter(blog__id=3)        # __exact is implied
>>> Entry.objects.filter(blog__pk=3)        # __pk implies __id__exact