【译】合理使用标准MODEL MANAGER
原文地址:https://www.idiotinside.com/2016/11/04/django-models-custom-manager-example/
Django model manager
一个Manager本质上来说,就是一个提供给Django model的数据库访问接口。对于Django应用程序中的每个Model都至少存在一个Manager。
每个Model有一个默认的manager "objects",这也是每个Model访问数据库的默认接口。
在本文中,我们使用employees用例来进行说明。
from django.db import models
class Employee(models.Model):
sex = (('M', 'Male'), ('F', 'Female'))
departments = (
('Sales', 'Sales'),
('Marketing', 'Marketing'),
('Finance', 'Finance'),
('Engineering', 'Engineering'),
)
roles = (
('J', 'Junior'),
('S', 'Senior'),
('M', 'Manager'),
)
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
email = models.CharField(max_length=200)
gender = models.CharField(max_length=1, choices=sex)
department = models.CharField(max_length=120, choices=departments, null=True)
role = models.CharField(max_length=120, choices=roles, default='J')
salary = models.FloatField()
def __unicode__(self):
return self.first_name + self.last_name
修改默认model manager
如果你想使用“objects“作为一个字段名称,或者仅仅想使用其他名字来作为Manager,你可以简单的对Manager重命名就可以。重命名Manager的方法,就是在Model中定义一个modelsManager()类型的类属性。
from django.db import models
class Employee(models.Model):
# custom manager replaces objects manger
all_employees = models.Manager()
sex = (('M', 'Male'), ('F', 'Female'))
departments = (
('Sales', 'Sales'),
('Marketing', 'Marketing'),
('Finance', 'Finance'),
('Engineering', 'Engineering'),
)
roles = (
('J', 'Junior'),
('S', 'Senior'),
('M', 'Manager'),
)
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
email = models.CharField(max_length=200)
gender = models.CharField(max_length=1, choices=sex)
department = models.CharField(max_length=120, choices=departments, null=True)
role = models.CharField(max_length=120, choices=roles, default='J')
salary = models.FloatField()
def __unicode__(self):
return self.first_name + self.last_name
在上述例子中,Employee.objects会产生一个AttributeError异常,但是Employee.all_employees.all()会返回所有Person对象的列表。
普通Manager
在一个特定的Model中,你可以使用某些常见的Manager以对默认Manager的功能进行扩展。
这个功能在下面展示的"DRY"原则中益处良多。可以看到,通过书写合适的Manager,我们可以避免重复的书写过滤条件。
修改原始Manager,返回不同的数据集合
from django.db import models
class SeniorEmployeeModelManager(models.Manager):
def get_queryset(self):
return super(SeniorEmployeeModelManager, self).get_queryset().filter(role='S')
class ManagersModelManager(models.Manager):
def get_queryset(self):
return super(ManagersModelManager, self).get_queryset().filter(role='M')
class Employee(models.Model):
# custom managers replaces objects manger
all_employees = models.Manager()
all_senior_employees= SeniorEmployeeModelManager()
all_managers = ManagersModelManager()
sex = (('M', 'Male'), ('F', 'Female'))
departments = (
('Sales', 'Sales'),
('Marketing', 'Marketing'),
('Finance', 'Finance'),
('Engineering', 'Engineering'),
)
roles = (
('J', 'Junior'),
('S', 'Senior'),
('M', 'Manager'),
)
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
email = models.CharField(max_length=200)
gender = models.CharField(max_length=1, choices=sex)
department = models.CharField(max_length=120, choices=departments, null=True)
role = models.CharField(max_length=120, choices=roles, default='J')
salary = models.FloatField()
def __unicode__(self):
return self.first_name + self.last_name
在这个例子中,创建了两个普通的Manager:"all_senior_employees", "all_managers".
Employee.all_senior_employees.all()返回所有高级雇员的信息列表,而Employee.all_managers则返回所有管理人员的列表。
作为一个常见的例子,在某些复杂的Model中,我们可以采用类似的技术。