管理器Manager
管理器是Django 的模型进行数据库查询操作的接口。Django 应用的每个模型都拥有至少一个管理器
管理器的名字 objects
默认情况下,Django 为每个模型类添加一个名为objects的管理器
如果你不想使用objects
,而是自定义
如果你想将objects用于字段名称,或者你想使用其它名称而不是objects访问管理器
在模型中定义一个值为models.Manager()的属性,来重命名管理器。例如:
from django.db import models
class Person(models.Model):
#...
people = models.Manager() # 这样就把管理器objects修改为了people
# 使用
之前是Person.objects.all()
现在是Person.people.all()会返回一个包含所有Person对象的列表。
修改管理器的原因:
你有两个原因可能会自己定义管理器:1.
向管理器类中添加额外的方法 2.
修改管理器返回的原始查询集。
一: 向管理器类中添加额外的方法
例如,下面这个自定义管理器提供一个with_counts() 方法,它返回所有OpinionPoll 对象的列表,列表的每项都有一额外num_responses 属性,该属性保存一个聚合查询的结果(注:对应的应是SQL查询语句中的COUNT(*)生成的项):
在该例中,你可以使用OpinionPoll.objects.with_counts() 返回带有num_responses 属性的OpinionPoll 对象列表。注意是对象
列表
from django.db import models
class PollManager(models.Manager):
def with_counts(self):
from django.db import connection
cursor = connection.cursor()
cursor.execute("""
SELECT p.id, p.question, p.poll_date, COUNT(*)
FROM polls_opinionpoll p, polls_response r
WHERE p.id = r.poll_id
GROUP BY p.id, p.question, p.poll_date
ORDER BY p.poll_date DESC""")
result_list = []
for row in cursor.fetchall():
p = self.model(id=row[0], question=row[1], poll_date=row[2])
# 管理器方法可以通过self.model 来得到它所属的模型类。
# 这里相当于创建了很多OpinionPoll类的实例,然后添加到列表里面,这也正符合django的查询集返回格式
p.num_responses = row[3]
result_list.append(p)
return result_list
class OpinionPoll(models.Model):
question = models.CharField(max_length=200)
poll_date = models.DateField()
objects = PollManager()
class Response(models.Model):
poll = models.ForeignKey(OpinionPoll)
person_name = models.CharField(max_length=50)
response = models.TextField()
二:修改管理器的原始查询集
管理器自带的 查询集返回系统中所有的对象。例如,使用下面这个模型:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
# Book.objects.all() 语句将返回数据库中所有的 Book 对象。
修改返回的查询集,也就是在查询集之后做一些操作
方法:
通过重写Manager.get_queryset() 方法来覆盖管理器自带的Queryset , get_queryset() 会根据你所需要的属性返回查询集。
例如,下面的模型有两个管理器,一个返回所有的对象,另一个则只返回作者是Roald Dahl 的对象:
# First, define the Manager subclass.
class DahlBookManager(models.Manager):
def get_queryset(self):
return super(DahlBookManager, self).get_queryset().filter(author='Roald Dahl')
# Then hook it into the Book model explicitly.
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
objects = models.Manager() # The default manager.
dahl_objects = DahlBookManager() # The Dahl-specific manager.
Book.objects.all()将返回数据库中所有的图书
Book.dahl_objects.all() 只返回作者是 Roald Dahl 的图书。
同时定义多个管理器,
该例还展示了另外一个很有意思的技巧:同一模型使用多个管理器。你可以依据你自己的偏好在一个模型里面添加多个 Manager() 实例。这是给模型添加通用过滤器(选择器)的一个简单方法:
class AuthorManager(models.Manager):
def get_queryset(self):
return super(AuthorManager, self).get_queryset().filter(role='A')
class EditorManager(models.Manager):
def get_queryset(self):
return super(EditorManager, self).get_queryset().filter(role='E')
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
role = models.CharField(max_length=1, choices=(('A', _('Author')), ('E', _('Editor'))))
people = models.Manager()
authors = AuthorManager()
editors = EditorManager()
网友评论