2009-02-01 2 views
10

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


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)) 

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

ответ

4

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

Более подробную информацию о моделях, см: http://docs.djangoproject.com/en/dev/topics/db/models/

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

Более подробную информацию о экземпляров модели, см: http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs

+0

Danke Schon Энди! – Geo

+0

Некоторые хорошие ссылки здесь, но «в этот момент они по существу ведут себя как переменные экземпляра» - это немного ручная маска, которая не очень точна (или, по крайней мере, ничего не объясняет). –

+1

Достаточно честно ... Я подниму руки к этому. +1 на ваш ответ. :) –

19

Суть вашего вопроса «, как приходят эти переменные класса (которые я присваивают объекты Field в) внезапно становятся переменными экземпляра (который я задаю данные) в Django's ORM "? Ответ на это - магия Python metaclasses.

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

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

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

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

+0

+1: Это круто вуду. Это не то, что вам следует глубоко понять. Но вам нужно увидеть, что он сгибает очевидные правила переменных экземпляра, добавляя еще один слой к способу создания объектов. –

+0

Хорошее объяснение. – Harold

+0

Прохладный. Я просто задаюсь вопросом: является ли атрибут '_meta' частью официального API-интерфейса модели? – pcv

0

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

Person.first_name 

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

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

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

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

так, например

peoples = Person.objects.all() 
Смежные вопросы