2017-11-25 1 views
0

참고 문헌과 예제를 계속 살펴 보았지만 여전히이 권리를 얻을 수는 없습니다.Python 3/Django에서 메타 클래스를 올바르게 사용하기

장고는 전달 된 값과 관련된 모든 종류의 메소드 등을 만드는 팩토리 시스템의 일부로 메타 클래스를 사용하는 많은 예제를 제공합니다. 아이디어는 명확합니다. 그러나 그것이 정말로 어떻게 작동하는지는 조금 신비 롭습니다.

장고의 전형적인 조각 (직선 장고에서이 '시작'튜토리얼)

코드는 다음과 같습니다

from django.db import models 

class Question(models.Model): 
    question_text = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 


class Choice(models.Model): 
    question = models.ForeignKey(Question, on_delete=models.CASCADE) 
    choice_text = models.CharField(max_length=200) 
    votes = models.IntegerField(default=0) 

을 이제 나중에,이 클래스의 실제 인스턴스, 예를 들어있을 것이다 :

q1 = Question(question_text='my question', pub_date='01-01-2017') 

그러나 모든 세계에서 클래스 정의 내에서 question_text와 pub_data는 클래스 전체 개체 (즉, q1, q2 등의 해당 클래스의 모든 인스턴스에서 공유 됨)처럼 보입니다.

클래스 데프이처럼 보였다 있도록 각 앞에 '자기'가있을이 될 것 격리이 작업을 수행하고 유지하는 전통적인 방법 :

class Question(models.Model): 
    self.question_text = models.CharField(max_length=200) 
    self.pub_date = models.DateTimeField('date published') 

나는 심지어보고 시도 장고 소스 코드. 실제로 models.Model은 모델을 기반으로하는 새 클래스가 선언 될 때마다 호출되는 메타 클래스가있는 클래스입니다. 모델입니다. 그러나이 코드는 상당히 비밀 스럽다.

여기에 어떤 관용구가 있습니까? 클래스에서 선언 된 변수가 인스턴스간에 공유 될 수 없다고 가정합니다. 어쩌면 상상할 수있는 바를 (그리고 당신이 원한다면) 그들의 속성을 내부 속성에 넣는 방법 일 뿐이라고 주장한다. 메타 클래스는 일을 만들어 일종의 결과로 이끌 수있는 마술을한다. 그게 더 논리적으로 보입니다. 어떻게 든

하지만, 코드를 따라 간다 하나는 같은 다른 인스턴스를 생성 같이

q2 = Question(question_text='my next question', pub_date='01-02-2017') 

데모 코드가 같은 경우 ACR 있도록, q1.question_text 또는 q2.pub_date을 참조하는 경우 잘 작동합니다 클래스 선언에서 선언 된 변수는 실제로 '자체'를가집니다. 선매.

호기심, 여기 장고 소스 (모델은 라인 (383)에 있고, 위 메타 클래스의 사용)이다 https://github.com/django/django/blob/master/django/db/models/base.py

답변

2

필드에서, DB 스키마 열 표현을 의미 클래스 - 아르는 수준이지만 값은 인스턴스 수준입니다.

class WithInt(models.Model): 
    fld = models.IntegerField() 

이 의미 :

type(WithInt.fld) # IntegerField 
inst = WithInt.objects.get(1) 
type(inst.fld) # int 
+0

이 SO, 다음과 같은 두 가지에 해당하는

당신이 IntegerField을 말해봐? (1) 클래스 전체 var fld는 데이터베이스 값이 아니라, 어떤 모델에 따라 파일링 된 데이터베이스에 대한 설명을 포함합니다 .IntegerField는/않습니다 (예 : 유형 설명자 일 수도 있지만 데이터베이스 테이블을 가리킬 수도 있음). 들판, 또는 무엇이든). (2) WithInt 클래스의 인스턴스에는 정수인 private 필드 (self.fld)가 있습니까? 나는 이것이 사실이라면 metaclass가 올바른 dicts/structures에 self.xxx 속성을 넣는 더러운 작업을 수행한다고 추정한다. – eSurfsnake

+0

맞아.메타 클래스는 모든 것을 뒤에서 처리합니다. – cwallenpoole

+0

감사합니다 - 뒤에서 일어나는 모든 일로 이해하기 쉽지 않습니다. – eSurfsnake

관련 문제