Django의 메타 클래스는 어떻게 작동합니까?


191

사람들이를 사용하여 클래스에 추가 매개 변수를 추가 할 수있게 해주는 Django를 사용하고 있습니다 class Meta.

class FooModel(models.Model):
    ...
    class Meta:
        ...

파이썬 문서에서 찾은 유일한 것은 :

class FooMetaClass(type):
    ...

class FooClass:
    __metaclass__ = FooMetaClass

그러나 나는 이것이 같은 것이라고 생각하지 않습니다.


6
제목은 파이썬 메타에 대해 묻지 만 장고 메타에 대해 묻는 것 같습니다.
ckhan

10
@ckhan 그는 중첩 된 클래스 "Meta"를 호출하는 터무니없는 결정 (IMO)으로 인해 혼란스러워합니다. 초보자, 파이썬의 메타 클래스 및 경험이없는 사용자, 클래스 특성 또는 실제 메타 클래스 대신
우선 순위에 대해

답변:


233

두 가지 다른 점에 대해 질문하고 있습니다.

  1. Meta장고 모델의 내부 클래스 :

    이것은 일부 옵션 (메타 데이터)이 모델에 첨부 된 클래스 컨테이너입니다. 사용 가능한 권한, 관련 데이터베이스 테이블 이름, 모델이 추상적인지 여부, 단수형 및 복수형 이름 등을 정의합니다.

    짧은 설명은 여기 있습니다 : Django 문서 : 모델 : 메타 옵션

    사용 가능한 메타 옵션 목록은 다음과 같습니다. 장고 문서 : 모델 메타 옵션

    Django의 최신 버전 : Django Docs : Model Meta 옵션

  2. 파이썬의 메타 클래스 :

    가장 좋은 설명은 여기 있습니다 : 파이썬에서 메타 클래스 란 무엇입니까?


3
이 두 가지는 전혀 관련이 있습니까? 즉, Django의 Meta내부 클래스는 파이썬의 내장 메타 클래스 기능을 사용하지 못하게합니까?
nnyby

10
@nnyby :이 두 개념 사이에 관계를 만드는 두 가지가 있습니다. OP는 원래 질문에서와 같이 많은 사용자가 가지고있는 이름과 혼란입니다. 나는 일반적인 혼란을 해결하는 것이이 토피의 중요한 이점이라고 생각합니다. 동의하지 않습니까?
Tadeck

49

위의 Tadeck의 Django 답변을 확장하면 Django에서 'class Meta :'를 사용하는 것은 일반적인 Python이기도합니다.

내부 클래스는 클래스 인스턴스간에 공유 데이터를위한 편리한 네임 스페이스입니다 (따라서 '메타 데이터'의 이름은 Meta이지만 원하는대로 호출 할 수 있습니다). Django에서는 일반적으로 읽기 전용 구성 요소이지만 변경을 멈추는 것은 없습니다.

In [1]: class Foo(object):
   ...:     class Meta:
   ...:         metaVal = 1
   ...:         
In [2]: f1 = Foo()
In [3]: f2 = Foo()
In [4]: f1.Meta.metaVal
Out[4]: 1
In [5]: f2.Meta.metaVal = 2
In [6]: f1.Meta.metaVal
Out[6]: 2
In [7]: Foo.Meta.metaVal
Out[7]: 2

Django에서 직접 탐색 할 수도 있습니다. 예 :

In [1]: from django.contrib.auth.models import User
In [2]: User.Meta
Out[2]: django.contrib.auth.models.Meta
In [3]: User.Meta.__dict__
Out[3]: 
{'__doc__': None,
 '__module__': 'django.contrib.auth.models',
 'abstract': False,
 'verbose_name': <django.utils.functional.__proxy__ at 0x26a6610>,
 'verbose_name_plural': <django.utils.functional.__proxy__ at 0x26a6650>}

그러나 Django 에서는 모델이 생성 될 때 모델이 생성 _metaOptions객체 인 속성 을 탐색하려고합니다 metaclass. 이곳에서 Django 클래스 '메타'정보를 모두 찾을 수 있습니다. 장고에서는 객체 Meta를 만드는 과정에 정보를 전달하는 데 사용됩니다 _meta Options.


사용자 정의 모델에서는 작동하지 않습니다. >>> myapp.models에서 가져 오기 MyModel >>> MyModel.Meta Traceback (가장 최근 호출) : <module> AttributeError의 파일 "<console>", 라인 1, 유형 객체 'MyModel'에는 'meta'속성이 없습니다.
bdf

2
당신은 밑줄이 필요합니다MyUser.objects.get(pk=1)._meta
Paul Whipp

그러나 모델의 내부 메타 클래스에는 액세스 할 수 없습니다. 해당 모델의 인스턴스에 대한 _meta 옵션에 액세스합니다 ... 내부 메타 클래스 자체에 액세스하는 방법은 없습니다. 나를위한 유스 케이스는 MyModelProxy가 MyModel의 내부 Meta 클래스를 상속 할 수있는 방식으로 MyModel에서 프록시 MyModelProxy 클래스를 서브 클래스 화했습니다.
bdf December

모델의 '내부 메타 클래스'가 무엇을 의미하는지 완전히 명확하지는 않지만 인스턴스 클래스를 사용하여 항상 직접 작업 할 수 있습니다.type(MyUser.objects.get(pk=1)).Meta
Paul Whipp

3
"클래스 인스턴스간에 공유 데이터를위한 편리한 네임 스페이스"그 줄이 저에게 도움이되었습니다.
MGP

22

Django의 Model클래스 Meta는 클래스 라는 속성을 갖는 것을 처리합니다 . 일반적인 파이썬이 아닙니다.

파이썬 메타 클래스는 완전히 다릅니다.


12
나는 당신의 대답이 명확하지 않다고 생각합니다. Meta수업이 어떻게 진행되는지 자세히 설명해 주 시겠습니까? OP가 구체적으로 물었다 고 생각합니다.
Tadeck April

7

Django 모델 Meta과 메타 클래스가 "완전히 다르다" 고 주장하는 답변 은 잘못된 답변입니다.

Django 모델 클래스 객체 (즉, 클래스 정의 자체를 나타내는 객체; 클래스도 객체입니다)의 구성은 실제로이라는 메타 클래스에 의해 제어됩니다. ModelBase여기에서 코드를 볼 수 있습니다 :

https://github.com/django/django/blob/master/django/db/models/base.py#L61

그리고 그 중 하나는 유효성 검사 기계, 필드 세부 정보, 논리 저장 등을 포함하는 모든 장고 모델 ModelBase에서 _meta속성 을 만드는 것입니다 . 이 작업 중에 모델의 내부 Meta클래스에 지정된 항목을 읽고 해당 프로세스 내에서 사용합니다.

그렇습니다. 그렇지만 어떤 의미 Meta에서 메타 클래스는 다른 '사물'입니다. 장고 모델 구성의 역학 내에서 그들은 밀접한 관련이 있습니다. 그들이 어떻게 협력하는지 이해하면 한 번에 두 가지에 대한 통찰력이 깊어 질 것입니다.

이것은 Django 모델이 메타 클래스를 사용하는 방법을 더 잘 이해하는 데 유용한 정보 소스가 될 수 있습니다.

https://code.djangoproject.com/wiki/DevModelCreation

객체의 일반적인 작동 방식을 더 잘 이해하려면이 방법도 도움이 될 수 있습니다.

https://docs.python.org/3/reference/datamodel.html


0

내부 메타 클래스 문서이 장고 모델 메타 데이터 문서는 순서 옵션 (순서 지정), 데이터베이스 테이블 이름 (db_table) 또는 사람이 읽을 수있는 단수 및 복수 이름 (verbose_name 및 verbose_name_plural)과 같이 "필드가 아닌 모든 것"입니다. 필요하지 않으며 모델에 클래스 메타를 추가하는 것은 완전히 선택 사항입니다. https://docs.djangoproject.com/en/dev/topics/db/models/#meta-options


0

장고에서는 구성 클래스의 역할을하며 구성 데이터를 한 곳에 보관합니다 !!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.