Метод from_db
Метод from_db применяется к классу модели и вызывается автоматически при создании экземпляра модели из данных, полученных из базы данных. Этот метод позволяет кастомизировать процесс создания объекта из данных, полученных из базы данных. Он принимает три параметра: имя базы данных, список полей и список значений. Метод должен вернуть экземпляр модели, созданный из переданных данных.
Синтаксис
class MyModel(models.Model):
@classmethod
def from_db(cls, db, field_names, values):
# Кастомная логика создания объекта
return super().from_db(db, field_names, values)
Параметры метода
Метод from_db принимает следующие параметры:
-
db- имя базы данных, из которой были получены данные -
field_names- список названий полей, которые были загружены из базы -
values- список значений, соответствующих полям изfield_names
Метод должен вернуть экземпляр модели, созданный на основе переданных данных.
Пример . Использование
Рассмотрим модель, которая хранит данные о статье и автоматически преобразует заголовок к верхнему регистру при загрузке из базы:
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
@classmethod
def from_db(cls, db, field_names, values):
# Создаем объект стандартным способом
instance = super().from_db(db, field_names, values)
# Преобразуем заголовок к верхнему регистру
if 'title' in field_names:
title_index = field_names.index('title')
instance.title = values[title_index].upper()
return instance
Теперь при получении статьи из базы данных заголовок будет автоматически преобразован к верхнему регистру:
from myapp.models import Article
# Получаем статью из базы
article = Article.objects.get(id=1)
print(article.title)
Результат выполнения кода:
"ВЕЛИКОЛЕПНАЯ СТАТЬЯ"
Пример . С множественными преобразованиями
Метод from_db позволяет выполнять любые преобразования данных при загрузке из базы. Рассмотрим пример, где мы добавляем вычисляемые поля:
from django.db import models
class User(models.Model):
username = models.CharField(max_length=50)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
age = models.IntegerField()
is_active = models.BooleanField(default=True)
@classmethod
def from_db(cls, db, field_names, values):
# Создаем объект стандартным способом
instance = super().from_db(db, field_names, values)
# Добавляем вычисляемое поле full_name
instance.full_name = f"{instance.first_name} {instance.last_name}"
# Проверяем, что возраст положительный
if instance.age < 0:
instance.age = 0
return instance
После этого при получении пользователя из базы мы можем использовать вычисленное поле full_name:
from myapp.models import User
# Получаем пользователя из базы
user = User.objects.get(id=1)
print(user.full_name)
print(user.age)
Результат выполнения кода:
"Ivan Petrov"
"25"
Важные особенности
При использовании метода from_db следует помнить о следующих особенностях:
-
Метод вызывается только при создании объектов из результатов запроса к базе данных, а не при создании объектов через конструктор
Model -
Метод
from_dbне вызывается при обновлении существующих объектов черезrefresh_from_db -
Метод должен всегда вызывать
superдля корректной работы Django ORM
Смотрите также
-
метод
save,
который сохраняет объект в базу данных -
метод
refresh_from_db,
который обновляет объект из базы данных -
метод
clean,
который выполняет валидацию полей модели -
метод
delete,
который удаляет объект из базы данных