2011-11-13 222 views
12

我對使用Django自定義模型管理器的正確方式感到困惑 - 基於文檔,您可以爲一個模型創建一系列管理器作爲過濾的一種方式。但爲什麼不創建一個具有一系列過濾功能的經理類?一種方法比另一種更好嗎?爲什麼?Django自定義模型管理器

例如:

class MaleManager(models.Manager): 
    def get_query_set(self): 
     return super(MaleManager, self).get_query_set().filter(sex='M') 

class FemaleManager(models.Manager): 
    def get_query_set(self): 
     return super(FemaleManager, self).get_query_set().filter(sex='F') 

class Person(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female'))) 
    people = models.Manager() 
    men = MaleManager() 
    women = FemaleManager() 

class PersonManager(models.Manager): 
    def males(self): 
     return super(MaleManager, self).get_query_set().filter(sex='M') 

    def females(self): 
     return super(FemaleManager, self).get_query_set().filter(sex='F') 

class Person(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female'))) 
    people = PersonManager() 

Person.people.females() # to get list of females 
Person.people.males() # to get a list of males 

回答

12

隨着第一種方法可以編寫:

men = Person.men.all() 

peters_men = Person.men.filter(first_name='Peter') 

對於第二種方法get_query_set是從模型'繼承',那麼它將返回查詢集而不進行自定義。我不知道有什麼理由放棄你的第二種方法,如果你使用管理界面,你應該檢查這是否支持。

此外,對於第二種方法,你應該改正你的問題。是

class PersonManager(models.Manager): 
    def males(self): 
     return super(PersonManager, self).get_query_set().filter(sex='M') 

Read django manager doc:「你可以通過覆蓋Manager.get_query_set()方法來覆蓋一個經理的基本查詢集get_query_set()應該返回一個QuerySet與您所需要的性能。」

編輯2017請注意,get_query_set從djanto 1.7更名爲get_queryset。更多信息在Modifying a manager’s initial QuerySet

+1

是的,但兩種方法正在返回querysets ...所以不會Person.objects.females.filter(first_name ='簡')仍然工作? ... –

+1

@ 9位:不要忘了實際調用該方法。 –

+0

@ IgnacioVazquez-Abrams你是什麼意思? Person.people.females.filter(first_name ='Jane')不會調用方法然後過濾嗎? –

相關問題