1. 程式人生 > >【譯】合理使用標準MODEL MANAGER

【譯】合理使用標準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中,我們可以採用類似的技術。