2014-02-07 2 views
0

저는 파이썬 메타 프로그래밍 지식이 부족합니다. 다음과 같은 것을 가정 해 봅시다 :초록 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을 어떻게 추상화하고 Company, Publisher 및 다른 모델에서 사용할 수 있습니까? 나는 관리자 정의에서 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") 

나는 모든 모델 바보 클래스를 생성하지 않으려는 그런 식으로.

감사합니다. Daniel.