【譯】合理使用標準MODEL MANAGER
阿新 • • 發佈:2018-12-18
原文地址: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中,我們可以採用類似的技術。