python - модели - django добавить поле в модель
Как работают модели Django? (2)
Поэтому я могу создать модель 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)
в коде Python, отличном от Django, строка выше определяет переменную класса title типа models.TextField, и я могу получить к нему доступ также следующим образом: thing.__class__.title
( link )
Но в Django, когда я создаю экземпляр Something, у меня внезапно появляется атрибут title, где я могу получить / установить текст. И не могу получить к нему доступ с помощью thing.__class__.title
Title Итак, когда я выполняю thing.title, я обращаюсь не к переменной класса title, а к какому-либо сгенерированному атрибуту / свойству или?
Я знаю, что поля оказались в thing._meta.fields, но как? Что происходит и как?
1. Создает ли Django свойство "title" за кулисами?
2, что случилось с переменной класса "title"?
https://ffff65535.com
Python очень мощный и позволяет разработчику использовать самоанализ.
Джанго использует много метаклассов. и кажется, что модели. Модель тоже его использует. смотрите в django \ db \ models \ base.py
class Model(object):
__metaclass__ = ModelBase
Я думаю, что метакласс просто берет атрибуты классов, такие как Поле, и для всех новых экземпляров для этого подкласса Модели создайте соответствующую переменную.
1) да, django автоматически создает переменную экземпляра свойства "title" 2) таким же образом метакласс перемещает поля в метакласс ...
Я думаю, что трудно превзойти то, что в документации Django говорится по этому поводу.
Класс Model (см. Base.py) имеет атрибут метакласса, который определяет ModelBase (также в base.py) как класс для использования при создании новых классов. Итак, ModelBase. new вызывается для создания этого нового класса Example. Важно понимать, что мы создаем здесь объект класса, а не его экземпляр. Другими словами, Python создает то, что в конечном итоге будет связано с именем примера в нашем текущем пространстве имен.
По сути, metaclass определяет, как будет создаваться сам класс. Во время создания дополнительные атрибуты / методы / что угодно могут быть связаны с этим классом. Пример, который дает ответ , использует все атрибуты класса с прописной буквы.
# 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's 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 для моделей может переварить атрибуты, которые вы применили к классу, и добавить различные полезные атрибуты для проверки / и т. Д., Включая даже методы и что-нет.