Как работают поля модели Django? - PullRequest
10 голосов
/ 01 февраля 2009

Прежде всего, я не занимаюсь веб-программированием. Я столкнулся с Django и немного прочитал о моделях. Я был заинтригован следующим кодом (от djangoproject.com):


class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

    def __str__(self):
        # Note use of django.utils.encoding.smart_str() here because
        # first_name and last_name will be unicode strings.
        return smart_str('%s %s' % (self.first_name, self.last_name))

Насколько я понимаю, python first_name и last_name являются переменными класса, верно? Как это используется в коде (потому что я предполагаю, что настройка Person.first_name или Person.last_name повлияет на все экземпляры Person)? Почему так используется?

Ответы [ 3 ]

20 голосов
/ 01 февраля 2009

Суть вашего вопроса в том, «почему эти переменные класса (которым я назначаю объекты Field) вдруг становятся переменными экземпляра (которым я назначаю данные) в ORM Джанго»? Ответ на это - магия Python метаклассы .

Метакласс позволяет вам подключиться и изменить процесс создания класса Python (не создание экземпляра этого класса, создание самого класса).

Объект Model Django (и, следовательно, также ваши модели, которые являются подклассами) имеет метакласс ModelBase . Он просматривает все атрибуты класса вашей модели и любые, которые являются экземплярами подкласса Field, он перемещается в список полей. Этот список назначается в качестве атрибута объекта _meta, который является атрибутом класса модели. Таким образом, вы всегда можете получить доступ к фактическим объектам поля через MyModel._meta.fields или MyModel._meta.get_field('field_name').

Затем метод Model.__init__ может использовать список _meta.fields, чтобы определить, какие атрибуты экземпляра следует инициализировать при создании экземпляра модели.

Не бойтесь погрузиться в исходный код Django; это отличный источник образования!

4 голосов
/ 01 февраля 2009

Да, first_name и last_name являются переменными класса. Они определяют поля, которые будут созданы в таблице базы данных. Существует таблица Person, в которой есть столбцы first_name и last_name, поэтому на данном этапе имеет смысл находиться на уровне класса.

Подробнее о моделях см .: http://docs.djangoproject.com/en/dev/topics/db/models/

Когда дело доходит до доступа к экземплярам Person в коде, вы обычно делаете это через ORM Django, и в этот момент они по существу ведут себя как переменные экземпляра.

Подробнее об экземплярах моделей см .: http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs

0 голосов
/ 08 марта 2012

Не настоящий ответ, но для обогащения:

Person.first_name 

не будет работать

p = Person.objects.get(pk=x)
p.first_name

будет работать. поэтому экземпляр объекта person имеет имя и фамилию, а статический контекст Person - нет.

Также обратите внимание: в Django есть менеджеры моделей, которые позволяют "Person" выполнять статические операции с набором запросов. (https://docs.djangoproject.com/en/dev/topics/db/managers/#managers).

так например

peoples = Person.objects.all()
...