Подтвердить что ты не робот

Как работают модели Django?

Итак, я могу создать модель Django следующим образом:

from django.db import models

class Something(models.Model):
    title = models.TextField(max_length=200)

и я могу работать с ним следующим образом:

thing = Something()
#set title
thing.title = "First thing"
#get title
thing.title

Все работает так, как должно, но я хотел бы понять, КАК это работает.

title = models.TextField(max_length=200)

в коде, отличном от Django Python выше, задается заголовок переменной типа type models.TextField, и я мог бы получить к нему доступ также следующим образом: thing.__class__.title (ссылка)

Но в Django, когда я создаю экземпляр Something, у меня внезапно появился атрибут title, где я могу получить/установить текст. И не могу получить к нему доступ с помощью thing.__class__.title Так ясно, когда я делаю thing.title. Я не получаю доступ к переменной класса "title" , но некоторые сгенерированные атрибуты/свойства или?

Я знаю, что поля оказались в thing._meta.fields, но как? Что происходит и как?

1, Django создает свойство "title" за кулисами?

2, Что случилось с переменной класса "title" ?

4b9b3361

Ответ 1

Я думаю, что его трудно превзойти, что документация Django должна сказать об этом.

Класс Model (см. base.py) имеет атрибут метакласс, который определяет ModelBase (также в base.py) как класс для использования для создания новых классов. Итак, ModelBase. new вызывается для создания этого нового класса Example. Важно понимать, что мы создаем объект класса здесь, а не его экземпляр. Другими словами, Python создает то, что в конечном итоге будет связано с именем примера в нашем текущем пространстве имен.

В принципе metaclass определяет, как будет создан сам класс. Во время создания дополнительные атрибуты/методы/все могут быть привязаны к этому классу. Пример этого fooobar.com/questions/102/... дает, заглавные буквы всех атрибутов класса

# remember that `type` is actually a class like `str` and `int`
# so you can inherit from it
class UpperAttrMetaclass(type): 
    # __new__ is the method called before __init__
    # it the method that creates the object and returns it
    # while __init__ just initializes the object passed as parameter
    # you rarely use __new__, except when you want to control how the object
    # is created.
    # here the created object is the class, and we want to customize it
    # so we override __new__
    # you can do some stuff in __init__ too if you wish
    # some advanced use involves overriding __call__ as well, but we won't
    # see this
    def __new__(upperattr_metaclass, future_class_name, 
                future_class_parents, future_class_attr):

        attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)

        return type(future_class_name, future_class_parents, uppercase_attr)

Аналогичным образом метакласс Django для моделей может переварить атрибуты, которые вы применили к классу, и добавить различные полезные атрибуты для проверки /etc, включая даже методы и что-нет.

Ответ 2

python чрезвычайно эффективен и позволяет разработчику использовать интроверсию.

django использует много метакласса. и кажется, что models.Model использовать его тоже. см. Джанго\DB\модели\base.py

class Model(object):
    __metaclass__ = ModelBase

Я думаю, что метакласс просто возьмет атрибуты классов, такие как поле и для всех новых экземпляров для этого подкласса Model, создайте подходящую переменную.

1) yes, django создать переменную экземпляра свойства "title" автоматически 2) аналогичным образом метакласс переместит поля в метаклас...