2011-04-20 4 views
17

저는 Django와 Python의 초심자이고, 최근에 Django 문서에서 Model.get_FOO_display()와 같은 많은 메소드를 발견했습니다. 도움말 페이지에서는 FOO 대신 필드 이름을 사용할 수 있다고 말합니다. 나는 그것이 파이썬에서 어떻게 가능한지 알아 내려고 노력해 왔고 '모델'클래스 소스를 들여다 보았다.get_FIELD_display (django에서)는 어떻게 작동합니까?

def _get_FIELD_display(self, field): 
     value = getattr(self, field.attname) 
     return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True) 

내가가 Python으로 가능 방법을 이해 할 수 없습니다 : 이 난이 건너 왔어요 그래서이

class Person(models.Model): 
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES) 
p = Person(name='John', gender='M') 

p.get_gender_display() 

를 작성하는) 1, 어떻게합니까 파이썬 '변화'FIELD (또는 FOO)를성에 넣으시겠습니까? 일종의 파이썬 '사악한'표기법인가요? (미안하지만 좀 더 명확하게 물을 수 없다) 파이썬 맨 페이지를 가리킨다.

2) 왜 Model 클래스의 소스가 _get_FIELD_display()를 앞에 밑줄로 선언하지만 위에 나온 Python doc 추출물이 밑줄없이 "p.get_gender_display()"라고 쓰는 이유는 무엇입니까? 다시 한번 말하지만, 파이썬 맨 페이지를 주시겠습니까?

답변

22

이 모든 것은 메타 클래스를 통해 관리됩니다. 소스에서 ModelBase으로 설정된 __metaclass__ 특성을 Model 클래스가 정의한다는 것을 알 수 있습니다. 메타 클래스는 클래스가 인스턴스가 될 때 클래스에 있습니다.

Django 클래스가 인 경우으로 정의되면 메타 클래스가 호출됩니다. 그런 다음 메타 클래스는 모델 클래스의 속성을 결정하는 다양한 코드를 실행합니다. 따라서 모델 클래스에서 선언 된 필드를 반복하고 각각을 인스턴스 속성으로 지정합니다. 이것이 장고의 선언 구문이 작동하는 방법입니다. 그런 다음 각 필드의 contribute_to_class 메서드를 호출합니다.이 메서드는 모든 필드 관련 메서드를 클래스 자체에 추가하며 해당 메서드 중 하나는 _get_FOO_display 메서드입니다. 이 소스는 django/db/models/fields/__init__.py에서 확인할 수 있습니다.

_get_FIELD_displayget_myfieldname_display으로 변경하기 위해 "currying"이라는 기술을 사용합니다. 즉 정의 된 매개 변수 (이 경우에는 필드 이름)와 함께 원래의 방법을 적용하는 새로운 기능을 정의합니다.

이 모든 것에 관심이 있다면, Marty Alchin의 저서 Pro Django는 훌륭한 설명이 있습니다.

2

클래스의 마법 __getattr__ 메서드를 사용하여 이러한 종류의 기능을 구현할 수 있습니다. __getattr__obj.attribute에 대해 호출되며 objattribute이없고 구현시 원하는대로 반환 할 수 있습니다.

관련 문제