Django Model Mixins : models.Model에서 상속 받나요?


79

이것은 일반적으로 유용 할 수있는 Python Mixins에 대한 질문입니다. 제가 가장 잘 알고있는 사용 사례 인 장고 모델을 사용하고 있습니다.

믹스 인은 '객체'와 믹스 인하도록 설계된 클래스에서 상속해야합니까?

코드 별 예, 달성하려는 것에 따라 더 정확하거나 더 나은 것이 무엇입니까?

class TaggingMixin(models.Model):
    tag = models.ForeignKey(Tag)

    class Meta:
        abstract = True

class MyModel(models.Model, TaggingMixin):
    title = models.CharField(max_length=100)

아니면 이거:

class TaggingMixin(object):
    tag = models.ForeignKey(Tag)

    class Meta:
        abstract = True

class MyModel(models.Model, TaggingMixin):
    title = models.CharField(max_length=100)

나는 객체에서 상속하는 것이 올바른 방법이라고 생각합니다. 하지만 인터넷 전체에서 첫 번째 사례의 예를보고 있습니다.

편집 : 후속 질문을 별도의 질문으로 옮겼습니다 : Django Abstract Models 대 간단한 Python mixins 대 Python ABCs

답변:


83

Django는 모델 클래스와 관련하여 많은 메타 마법을 사용하므로 안타깝게도 Daniel Roseman의 답변에서 제안한 믹스 인에 대한 일반적인 접근 방식 object은 Django 세계에서 잘 작동하지 않습니다.

제공된 예제를 사용하여 믹스 인을 구성하는 올바른 방법은 다음과 같습니다.

class TaggingMixin(models.Model):
    tag = models.ForeignKey(Tag)

    class Meta:
        abstract = True

class MyModel(TaggingMixin):
    title = models.CharField(max_length=100)

여기서 중요한 점은 다음과 같습니다.

  • Mixins는 model.Model 되지만 추상 클래스로 구성됩니다.
  • mixin은에서 상속하기 때문에 model.Model실제 모델은 이로부터 상속 해서는 안됩니다 . 그렇게하면 일관된 메서드 해결 순서 예외가 트리거 될 수 있습니다.

1
결과적으로 TypeError: Cannot create a consistent method resolution order (MRO). 수행 class MyModel(TaggingMixin):하는 대신. 참조 stackoverflow.com/q/29214888/1627479
Joren

감사합니다 @Joren. 이를 반영하기 위해 답변을 편집했습니다.
jsdalton

22
여기서 "Mixin"은 잘못된 용어입니다. 그것은 단지 추상적 인 모델 일뿐입니다. 당신은 그것을 "믹스"할 수 models.Model또는 다른 추상적 인 모델
데이비드 Avsajanishvili

15

에서 상속하는 것이 좋습니다 object. 이렇게하면 실제로 명시 적으로 정의한 메서드와 속성 만 제공하도록 할 수 있습니다.

또한, 콘크리트 클래스를 정의 할 때 항상 mixin 클래스를 먼저 배치해야합니다 . 파이썬의 해결 규칙은 클래스 선언에서 정의 된 순서대로 수퍼 클래스가 검색되고 일치하는 속성이 발견되면 해결이 중지됨을 의미합니다. 따라서 mixin이 메인 슈퍼 클래스에서도 정의한 메서드를 정의하면 mixin 메서드를 찾을 수 없습니다.


12
mixin 클래스가 상속되지 않는 경우 필드를 추가하는 메타 클래스 매직이 작동하지 않는 경우를 제외하고 models.Model(또는 더 구체적 __metaclass__으로 필요한 것이없는 경우).
매튜 Schinckel

2
개체에서 상속이 작동하지 않았습니다. 참조 : stackoverflow.com/questions/17343867/…
utapyngo 2014

2
상속 객체는 장고에게 좋은 방법이 아닙니다. django makemigrations가 인식 할 수 없기 때문입니다. 마이그레이션 파일에는 해당 파일이 포함되어 있지 않습니다.
9nix00

템플릿으로 작은 예제를 추가하면 좋을 것입니다.
Pithikos

8

이것은 추상 모델 의 직업처럼 보입니다 .

편집하다:

그것들은 믹스 인 자체가 아닙니다. 또는 그럴 필요가 없습니다. 추상 모델에서 직접 파생 할 수 있습니다.


1
어, 맞아요. 이것은 추상적 인 모델을위한 일입니다. 사실 저는 코드에서 그것들을 잊어 버렸습니다. 제가 그것을 추가했지만 이제는 제 질문에 대해 더 혼란스러워지기 시작했습니다 .. .
hopla 2010-07-15

3

일반 Python 객체에서 상속 할 때 South는 마이그레이션을 생성하지 않으므로이 접근 방식을 사용할 수 없습니다.


1
남쪽 이주와는 아무 관련이 없습니다.
매튜 Schinckel

나는 접근 방식이 South와 잘
어울리지
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.