2014-02-07 80 views
0

我在這裏缺乏Python元編程知識。比方說,我有以下幾種:摘要Django模型管理器

class OwnCompanyManager(models.Manager): 
    """Only companies of this user""" 
    def get_queryset(self, user): 
     if user.is_superuser: 
      return super(OwnCompanyManager, self).get_queryset() 
     return super(OwnCompanyManager, self).get_queryset().filter(
      companyuser__user=user) 


class OwnPublisherManager(models.Manager): 
    """Only publishers of this user's company""" 
    def get_queryset(self, user): 
     if user.is_superuser: 
      return super(OwnPublisherManager, self).get_queryset() 
     return super(OwnPublisherManager, self).get_queryset().filter(
      company__companyuser__user=user) 

class Company(models.Model): 
    name = models.CharField(max_length=45) 

    objects = models.Manager() 
    own = OwnCompanyManager() 


class Publisher(models.Model): 
    company = models.ForeignKey(Company) 
    allow_latest_dev = models.BooleanField(default=False) 
    domains_blocked = models.BooleanField(default=False) 

    objects = models.Manager() 
    own = OwnPublisherManager() 

我還有很多。我不喜歡複製粘貼樣板Own(Publisher|Company|Etcetra)Manager)。正如你所看到的,唯一的變化就是過濾器。

如何抽象Own(InsertModelNameHere)Manager並從CompanyPublisher和其他模型中使用它?我想在管理器定義中指定過濾器kwargs。

回答

5

這裏不需要元編程或任何特別聰明的東西。你只需要提取改變的位。在這種情況下,它只是filter的參數:您可以使用參數傳遞的字典形式,並將過濾器作爲字符串存儲在類屬性中。

class AbstractManager(models.Manager): 
    def get_queryset(self, user): 
     if user.is_superuser: 
      return super(AbstractManager, self).get_queryset() 
     return super(AbstractManager, self).get_queryset().filter(**{self.filter: user}) 

class OwnCompanyManager(AbstractManager): 
    filter = "companyuser__user" 

class OwnPublisherManager(AbstractManager): 
    filter = "company__companyuser__user" 
+0

這看起來更好。但是,是否有可能擁有AbstractManager並且沒有其他類?即在模型定義中構建Manager類? –

1

丹尼爾的回答啓發:

class OwnManager(models.Manager): 
    def __init__(self, key): 
     super(OwnManager, self).__init__() 
     self.k = key 

    def get_queryset(self, user): 
     if user.is_superuser: 
      return super(OwnManager, self).get_queryset() 
     return super(OwnManager, self).get_queryset().filter(**{self.k: user}) 


class Company(models.Model): 
    name = models.CharField(max_length=45) 

    objects = models.Manager() 
    own = OwnManager("companyuser__user") 


class Publisher(models.Model): 
    company = models.ForeignKey(Company) 
    allow_latest_dev = models.BooleanField(default=False) 
    domains_blocked = models.BooleanField(default=False) 

    objects = models.Manager() 
    own = OwnManager("company__companyuser__user") 

這樣,我不想爲每個模型創建笨類。

謝謝丹尼爾。