在之前的帖子中,我介绍了如何通过 Django 的 ORM 处理数据,即 CRUD(创建、读取、更新、删除)操作。这一次,我将更深入地分析在示例中使用的 objects 管理器 到底是什么,它是如何构成的,以及它能做些什么。 objects 是理解 Django ORM 的关键概念。


1. objects 管理器是什么?

在 Django 模型的基本结构中,最常出现的就是 objects 这个管理器。 objects 被称为 Django 的模型管理器(Manager),负责查询或操作数据库记录。简而言之,objects 管理器就像模型类和数据库之间的桥梁。

Django objects manager diagram

模型类的基本属性 objects 是 Django 提供的 Manager 类的实例。通过这个实例,可以与数据库进行通信,进行数据的创建、检索、修改和删除等操作。例如,可以通过 Post.objects.all()Post.objects.create() 等方法访问数据。


2. Manager 类的角色

Manager 类是 Django 模型与数据库之间的接口,允许执行各种查询。Django 默认会为每个模型自动创建一个名为 objectsManager,并通过这个 Manager 来处理大多数的 CRUD 操作。

如何通过 objects 实现 CRUD,你可能已经有了一定的了解或经验。由于示例代码在之前的部分中已讨论过,这里将不再赘述。


3. 创建自定义 Manager

虽然默认提供的 objects 管理器非常有用,但有时可能需要 重用特定的查询逻辑 或执行更复杂的查询。在这种情况下,可以创建 自定义管理器 来添加所需的功能。

3.1 定义自定义 Manager 类

例如,我们可以创建一个只过滤已发布文章的自定义管理器。

from django.db import models

class PublishedManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status='published')

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    status = models.CharField(max_length=10, choices=[('draft', 'Draft'), ('published', 'Published')])
    publish_date = models.DateTimeField(auto_now_add=True)

    # 除了基本的 objects 管理器外,还添加自定义管理器
    published = PublishedManager()

在上面的示例中,我们定义了 PublishedManager 这个自定义管理器,并将其添加到 Post 模型中。这个 PublishedManager 只返回状态为 'published' 的文章。现在调用 Post.published.all() 时,您可以只获取已发布的文章。

3.2 自定义管理器的应用

  • 减少重复代码:使用自定义管理器可以减少每次添加过滤条件时的代码重复。
  • 封装特定查询逻辑:可以根据特定业务逻辑定制查询逻辑,让其在模型内整洁管理。

4. 使用 objects 管理器可以执行的各种操作

Django 的 objects 管理器除了基本提供 CRUD 功能外,还支持更多的数据库操作。

4.1 数据过滤

  • filter():查询满足条件的多个对象。
    published_posts = Post.objects.filter(status='published')
  • exclude():查询不符合特定条件的对象。
    draft_posts = Post.objects.exclude(status='published')

4.2 排序与切片

  • 排序:可以使用 order_by() 方法对数据进行排序。
    recent_posts = Post.objects.all().order_by('-publish_date')
  • 切片:像 Python 的列表切片一样,查询集也可以通过切片获取特定范围的数据。
    first_three_posts = Post.objects.all()[:3]

4.3 使用聚合函数

objects 管理器也提供聚合函数。例如,如果想知道文章的数量,可以使用 count() 方法。

post_count = Post.objects.count()

此外,可以使用 aggregate() 方法进行平均值、总和等聚合运算。

from django.db.models import Avg
average_length = Post.objects.aggregate(Avg('content_length'))

5. objects 管理器的工作原理

objects 管理器内部生成 查询集(QuerySet) 对象。查询集是一组用于从数据库获取数据的查询。当调用 objects.all()objects.filter() 等方法时,Django 会生成查询集,并在需要时将该查询传递给数据库以获取结果。

查询集使用 延迟评估(lazy evaluation)。这意味着在创建查询集时,并不实际访问数据库,而是在需要数据的时候执行数据库查询。通过这种方式,可以避免不必要的查询执行,从而实现高效的数据处理。


结束语

Django 的 objects 管理器是简化与数据库交互并轻松处理数据的强大工具。除了基本提供的 CRUD 功能外,还可以定义自定义管理器,重用特定查询逻辑或轻松处理更复杂的操作。此外,由于查询集的延迟评估等特性,也能实现高效的数据处理。

深入理解 Django ORM 的 objects 管理器,能够更高效地操作数据库,并在减少代码重复的同时保持代码的整洁性。希望您今后能更好地利用模型管理器,并在需要时引入自定义管理器,从而使 Web 应用程序的复杂数据处理变得更加简单和灵活。

在下一个部分,我将详细讨论 查询集(QuerySet)与数据查询。ORM 的优点之一是 "无需了解 SQL",而充分利用这一优势,理解下一个部分的内容将会非常重要。请期待下一篇。