Как это работает? Класс с экземплярами классов в качестве аттрибутов
Нашёл в одной задаче. Совершенно не понимаю концепцию написанного:
class User(Model):
first_name = CharField(max_length=30)
last_name = CharField(max_length=50)
email = EmailField()
user1 = User(first_name='Liam', last_name='Smith', email='[email protected]')
В задаче написано, что CharField и EmailField - это строки. Про CharField конкретно написано
CharField - a string with min_length (default 0) and max_length (default None) parameters.
Я понял только одну вещь, есть экземпляр user1 класса Userс аргументами:
first_name='Liam', last_name='Smith', email='[email protected]'
Поскольку у User нет __init__ он наследует его у Model.
А вот что значат:
first_name = CharField(max_length=30)
last_name = CharField(max_length=50)
email = EmailField()
Я не понимаю... Это имеет какое-то отношение к метаклассам? Я нигде не могу найти информацию по подобной конструкции и её назначении.
Ответы (1 шт):
На уровне питона это просто создание атрибутов класса. Т.е. first_name = CharField(max_length=30) добавляет в класс User атрибут с именем first_name и значением типа CharField созданным конструктором CharField с соответствующими параметрами. Добавляет именно в класс, а не в конкретный экземпляр класса.
Теперь, как эти атрибуты класса используются. В классе Model реализован определенный функционал, которы позволяет среди прочего сохранять экземпляры класса в БД, делать запросы к БД используя удобный синтаксис (без SQL) и еще много чего.
Работает это таким образом, что атрибуты класса описывают, какие поля могут храниться экземпляре, их типы, ограничения и т.п.
Конструктор из Model работает (упрощенно) так: берет именованные аргументы (в этом примере first_name='Liam', last_name='Smith', email='[email protected]') и проверяет, что в классе есть атрибуты с соответствующими именами, что типы переданных аргументов совпадают. Далее он сохраняет эти аргументы в полях экземпляра.
Еще в Model есть функция save, которая позволяет сохранить объект в таблицу БД, которая имеет структуру (т.е. набор полей) такую какая задана атрибутами класса User. При этом типы полей соответствуют типам атрибутов в User. Для этого save строит SQL команду типа INSERT INTO имя_таблицы (поле1, поле2, ...) values (значение_поля1, ....). Именно тут нужно знать список полей их типы и т.д.
Далее Model позволяет делать запросы в БД. Например, можно поискать пользователей с заданным именем:
users = User.objects.filter(first_name='Bob')
Опять же параметры, которые можно передать в filter базируются на полях определенных в модели User.