2010-06-24 6 views
7

를 조회하여 서브 클래스를 가져옵니다 :장고 모델의 서브 클래스 : 다음 코드가 주어 슈퍼 클래스

class BaseMedium(models.Model): 
    title = models.CharField(max_length=40) 
    slug = models.SlugField() 

class A(BaseMedium): 
    url = models.URLField() 

class B(BaseMedium): 
    email = models.EmailField() 

내가 지금 모든 BaseMedium을 조회 할.

b = BaseMedium.objects.all() 

하위 클래스 유형을 모르는 상태에서 하위 클래스 필드를 포함한 모든 정보를 어떻게 인쇄합니까? b[0]가 실제로 A 인스턴스에 관련이 있는지

b[0].a이 정보를 인쇄 할하지만이 B에 관련이 경우는 DoesNotExist 예외를 인쇄합니다.

이것은 의미가 있지만 관련 변수를 반환하거나 관련 개체를 반환하고 싶습니다.

어쩌면 저의 데이터베이스 레이아웃은 위와 같은 방법으로 쿼리하는 것이 좋지 않을 수도 있습니다. 그렇다면 더 나은 레이아웃을 추천 해 주시면 기쁠 것입니다.

은 내가 GenericForeignKey

class Generic(models.Model): 
    basemedium = models.ForeignKey('BaseMedium') 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    object = generic.GenericForeignKey('content_type', 'object_id') 

사용에 대한 생각하지만,이 솔루션은 복잡한에 될 것으로 보인다 나는 너희들이 더 나은 솔루션을 가지고 생각합니다.

답변

2

이 작업을 수행하는 유일한 방법은 명시 적으로 기본 모델에 어떤 형식인지 저장하는 것입니다. baseMedium에 derived_type (또는 무엇이든) 필드가 있고 저장시 설정하십시오. 그런 다음 get_derived_type 방법을 사용할 수 있습니다.

def get_derived_type(self): 
    if self.derived_type == 'A': 
     return self.a 
    elif self.derived_type == 'B': 
     return self.b 

등이 있습니다.

1

감사합니다. Roseman 귀하의 회신에 대한. 나는 당신의 아이디어를 조금 더 발전 시켰습니다.

def related_object(self, default_pointer_name='_ptr'): 
     models = [A,B] #models 
     object = None 

     argument = '%s%s' %(self.__class__.__name__.lower(), default_pointer_name) 
     query = { argument : self} 

     for model in models: 
      try: 
       object = model.objects.get(**query) 
      except model.DoesNotExist: 
       pass 
      else: 
       return object 

     if object == None: 
      raise RelatedObjectException 
     return object 

이 BaseMedium 사용하는 방법입니다 : 는 여기에 내가 무엇을 최대 온 것입니다.

+0

이 항목을주의해야합니다. DB에서 검색 할 레코드가 1000 개이면 하나의 SELECT에서 수행되지만 1000 개의 단일 선택으로 각 BaseMedium 객체에 대한 하위 유형을 가져옵니다. 어쨌든 나는 그것을하는 더 좋은 생각을 모른다. 나는 여분의 db 쿼리를 많이 생성하는 similarar를 사용합니다 ... – dzida

+1

당신이 맞습니다. 사용자 지정 SQL은 옵션 일 수 있습니다 ... 이상한 일은 알려진 솔루션의 일반적인 문제가 아닌 방법입니다. – rotrotrot

3

얼마 전에 해결책 posted by Carl Meyer을 확인해야합니다. 내부적으로 ContentType 방식을 사용하지만 매우 우아하게 캡슐화합니다.

그는 또한 데이터베이스에 선택 필드를 저장할 필요가 없지만 직접 하위 클래스에서만 작동하는 대안적이고 효율적인 솔루션을 지적합니다. 상속 수준이 여러 개인 경우 첫 번째 해결 방법이 더 좋습니다.

관련 문제