Как работает get_FIELD_display (в django)? - PullRequest
19 голосов
/ 20 апреля 2011

Я новичок в Django и Python, и недавно натолкнулся на ряд методов в Django docs, таких как Model.get_FOO_display ().Страница справки говорит, что вы можете заменить FOO на имя поля.Я пытался выяснить, как это возможно в Python, и изучил класс «Модель».Там я наткнулся на это:

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

Я не могу понять, как в Python можно: 1) написать это

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

p.get_gender_display()

Итак, как Python «меняет» ПОЛЕ(или FOO) в пол?Это что-то вроде злой нотации Python?(Извините, я не могу спросить более четко) Можете ли вы указать на какую-нибудь справочную страницу Python?

2) почему источник из класса Model объявляет _get_FIELD_display () с начальным подчеркиванием, а Python doc извлекает из приведенного вышепишет "p.get_gender_display ()" без подчеркивания?Опять же, не могли бы вы дать справочную страницу Python для этого?

Ответы [ 2 ]

23 голосов
/ 20 апреля 2011

Все это управляется через метакласс - в источнике вы увидите, что класс Model определяет атрибут __metaclass__, который установлен в ModelBase. Метакласс относится к классу как класс к экземпляру.

Таким образом, метакласс вызывается, когда класс Django определен . Затем метакласс выполняет различный код, который определяет свойства класса модели. Таким образом, он просматривает поля, объявленные в классе модели, и назначает каждое из них в качестве атрибута экземпляра - так работает декларативный синтаксис Django. Затем он вызывает метод contribute_to_class каждого поля, который добавляет любые специфичные для поля методы к самому классу, и одним из этих методов является метод _get_FOO_display. Вы можете увидеть источник этого в django/db/models/fields/__init__.py.

Чтобы изменить _get_FIELD_display на get_myfieldname_display, он использует технику, называемую «curry», что означает, что он определяет новую функцию, которая применяет оригинальный метод с определенным параметром - в данном случае, имя поле.

Если вам все это интересно, у книги Марти Алчина «Про Джанго» отличное объяснение.

2 голосов
/ 20 апреля 2011

Волшебный метод __ getattr __ для классов может использоваться для реализации такого рода функциональности.__getattr__ вызывается для каждого obj.attribute, где attribute не существует на obj, и реализация может возвращать все, что пожелает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...