Создание моделей контента
Модель Content приложения courses содержит универсальные связи для связывания с ним различных типов содержимого. Мы создадим отдельную модель для каждого типа содержимого. Все модели содержимого будут иметь несколько общих полей и дополнительные поля для хранения пользовательских данных. Мы собираемся создать абстрактную модель, которая предоставляет общие поля для всех моделей контента.
Отредактируйте файл models.py приложения courses и добавьте в него следующий код:
class ItemBase(models.Model):
owner = models.ForeignKey(User, related_name='%(class)s_related')
title = models.CharField(max_length=250)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
def __str__(self):
return self.title
class Text(ItemBase):
content = models.TextField()
class File(ItemBase):
file = models.FileField(upload_to='files')
class Image(ItemBase):
file = models.FileField(upload_to='images')
class Video(ItemBase):
url = models.URLField()
В этом коде мы определили абстрактную модель с именем ItemBase. Таким образом, мы установили abstract=True в классе Meta. В этой модели мы определили поля owner, title, created и updated. Эти общие поля будут использоваться для всех типов содержимого. Поле owner позволяет сохранить пользователя, создавшего контент. Поскольку это поле определено в абстрактном классе, для каждой наследуемой модели необходимо отличать related_name. Джанго позволяет указать placeholder для имени класса модели в атрибуте related_name в виде '%(class)s_related'. Таким образом, related_name для каждой дочерней модели будет сгенерирован автоматически. Поскольку мы используем '%(class)s_related' как related_name, обратная связь для дочерних моделей будет text_related, file_related, image_related, и video_related соответственно.
Мы определили четыре различных модели содержимого, которые наследуются от абстрактной модели ItemBase. К ним относятся:
- Text : Для хранения текстового содержимого.
- File : Для хранения файлов, таких как PDF.
- Image : Для хранения изображений.
- Video : Для хранения видео. Мы используем поле URLField для предоставления URL-адреса видео.
Каждая дочерняя модель содержит поля, определенные в классе ItemBase, в дополнение к собственным полям. Для моделей Text, File, Image, и Video будет создана таблица базы данных. Но не будет никакой таблицы базы данных, связанной с моделью ItemBase, поскольку она является абстрактной моделью.
Отредактируйте ранее созданную модель Content и измените ее поле content_type следующим образом:
content_type = models.ForeignKey(ContentType, limit_choices_to={'model__in': ('text',
'video',
'image',
'file')})
Мы добавили аргумент limit_choices_to для ограничения объектов ContentType, которые могут быть использованы для универсальной связи. Мы используем поля model__in для фильтрации запроса к объектам ContentType с атрибутом model, который является 'text', 'video', 'image' или 'file'.
Давайте создадим миграцию для включения новых моделей. Выполните следующую команду из командной строки:
python manage.py makemigrations
Вы увидите следующие выходные данные:
Migrations for 'courses':
0002_content_file_image_text_video.py:
- Create model Content
- Create model File
- Create model Image
- Create model Text
- Create model Video
Затем выполните следующую команду, чтобы применить новую миграцию:
python manage.py migrate
Вывод, который вы увидите, должен закончиться следующим образом:
Running migrations:
Rendering model states... DONE
Applying courses.0002_content_file_image_text_video... OK
Мы создали модели, которые подходят для добавления разнообразного содержимого в модули курсов.