Создание моделей для неоднородного контента
Мы планируем добавить различные типы содержимого в модули курсов, такие как текст, изображения, файлы и видео. Нам нужна универсальная модель данных, которая позволяет хранить разнообразные материалы. В главе 6 «Tracking User Actions» вы узнали о удобном использовании типовых отношений для создания внешних ключей, которые могут указывать на объекты любой модели. Мы собираемся создать модель Content, представляющую содержимое модулей, и определить универсальное отношение для связывания любого вида содержимого.
Отредактируйте файл models.py приложения courses и добавьте следующие импорты:
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
Затем добавьте следующий код в конец файла:
class Content(models.Model):
module = models.ForeignKey(Module, related_name='contents')
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
item = GenericForeignKey('content_type', 'object_id')
Это модель Content. Модуль содержит multiple contents, поэтому мы определим поле ForeignKey в модели Module. Мы также установили общую связь для связывания объектов из различных моделей, представляющих различные типы содержимого. Помните, что для настройки универсальных отношений необходимы три разных поля. В нашей модели Content они следующие:
- content_type : Поле ForeignKey в модели ContentType
- object_id : Это PositiveIntegerField для хранения первичного ключа связанного объекта
- item : GenericForeignKey поле связанное с объектом с помощью объединения двух предыдущих полей
Только поля content_type и object_id имеют соответствующий столбец в таблице базы данных этой модели. Поле item позволяет извлечь или задать связанный объект напрямую, а его функциональность построена поверх остальных двух полей.
Мы будем использовать раздичные модели для каждого типа содержимого. В наших моделях содержимого будут иметься некоторые общие поля, но они будут отличаться в фактическом содержимом, которое они могут хранить.