Django База [2023]: Создаем модуль Блог и модель Статьи 📰 #2
Django

Django База [2023]: Создаем модуль Блог и модель Статьи 📰 #2

Razilator

В уроке два по созданию Django приложения, мы займемся добавлением модуля Блог (Blog), в котором создадим модель статьи (Article).

Открытие проекта в редакторе / настройка виртуального окружения

Открываем наш проект, созданный в предыдущем уроке #1 через редактор. Я использую VSCODE. Вы можете использовать и лобые другие редакторы, например PyCharm.

Открыв наш проект, переходим в терминал. Чтобы открыть терминал в VSCODE, его необходимо создать: Терминал -> Создать терминал

Создание терминала и активация вирт.окружения
Создание терминала и активация вирт.окружения

Отлично, теперь активируем оболочку cmd, введя команду cmd в терминале. Далее нам необходимо активировать виртуальное окружение с помощью следующей команды:

cd venv/Scripts && activate && cd ../../  

После этого вы увидите в терминале в скобках (venv), это значит, что виртуальное окружение активировано, перейдите в каталог приложения с помощью команды cd backend

Создание приложения Blog

Теперь давайте создадим приложение Блог (Blog), делается это с помощью следующей команды:

py manage.py startapp blog

Отлично, мы создали первое приложение blog.

Созданное приложение blog
Созданное приложение blog

Давайте создадим папку modules, и в нее переместим созданное приложение.

Структура проекта получится следующего вида:

  • backend
  • modules
    • blog
  • db.sqlite3
  • manage.py

Перейдем в файл modules/blog/apps.py и отредактируем его, добавив, что он будет использоваться именно внутри папки modules, а также добавим лейбл на русском языке с помощью параметра verbose_name:

modules/blog/apps.py
from django.apps import AppConfig


class BlogConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'modules.blog'
    verbose_name = 'Блог'

Создание модели Article

Перейдем в файл models.py, в нем мы добавим следуюдующий код:

blog/models.py
from django.db import models
from django.core.validators import FileExtensionValidator
from django.contrib.auth import get_user_model


User = get_user_model()


class Article(models.Model):
    """
    Модель постов для сайта
    """    

    STATUS_OPTIONS = (
        ('published', 'Опубликовано'), 
        ('draft', 'Черновик')
    )

    title = models.CharField(verbose_name='Заголовок', max_length=255)
    slug = models.SlugField(verbose_name='URL', max_length=255, blank=True, unique=True)
    short_description = models.TextField(verbose_name='Краткое описание', max_length=500)
    full_description = models.TextField(verbose_name='Полное описание')
    thumbnail = models.ImageField(
        verbose_name='Превью поста', 
        blank=True, 
        upload_to='images/thumbnails/', 
        validators=[FileExtensionValidator(allowed_extensions=('png', 'jpg', 'webp', 'jpeg', 'gif'))]
    )
    status = models.CharField(choices=STATUS_OPTIONS, default='published', verbose_name='Статус поста', max_length=10)
    time_create = models.DateTimeField(auto_now_add=True, verbose_name='Время добавления')
    time_update = models.DateTimeField(auto_now=True, verbose_name='Время обновления')
    author = models.ForeignKey(to=User, verbose_name='Автор', on_delete=models.SET_DEFAULT, related_name='author_posts', default=1)
    updater = models.ForeignKey(to=User, verbose_name='Обновил', on_delete=models.SET_NULL, null=True, related_name='updater_posts', blank=True)
    fixed = models.BooleanField(verbose_name='Зафиксировано', default=False)

    class Meta:
        db_table = 'app_articles'
        ordering = ['-fixed', '-time_create']
        indexes = [models.Index(fields=['-fixed', '-time_create', 'status'])]
        verbose_name = 'Статья'
        verbose_name_plural = 'Статьи'

    def __str__(self):
        return self.title

Примечания за поля модели:

  • title - заголовок, с максимальным количеством символов 255
  • slug - ссылка на материал (латиница), или в простонародии ЧПУ-человеко-понятный урл, с максимальным количеством символов 255, blank (необязательно к заполнению)
  • short_description - текстовое поле, ограниченное 300 символами.
  • full_description - аналогично, без ограничений.
  • thumbnail - превью статьи.
  • status - опубликована статья, или черновик.
  • time_create и time_update - время создания и обновления статьи.
  • author - ключ ссылаемый на пользователя из другой таблицы (пользователей) c on_delete=models.PROTECT (при удалении происходит защита, что не позволяет так просто удалить пользователя с его статьями, чтоб вы могли передать статьи другому человеку)
  • updater - аналогично, только если при обновлении статьи выводить того, кто редактировал (добавлять, если вам это нужно) c on_delete=models.CASCADE (при удалении просто убирается значение того, кто обновил у статей каскадно)
  • fixed - булево значение, по умолчанию False (не закреплено)

Примечания в параметрах Meta:

  • ordering - сортировка, ставим -created_at, чтобы выводились статьи в обратном порядке (сначала новые, потом старые).
  • verbose_name - название модели в админке в ед.ч
  • verbose_name_plural - в мн.числе
  • db_table - название таблицы в БД. (можно не добавлять, будет создано автоматически)
  • indexes - индексирование полей, чтобы ускорить результаты сортировки.

Примечание о get_user_model():

get_user_model() - это удобный способ получить модель пользователя, определенную в проекте Django. Вместо того, чтобы явно импортировать модель пользователя (from django.contrib.auth.models import User), get_user_model() возвращает модель пользователя, которая настроена в настройках проекта (AUTH_USER_MODEL).

Основные преимущества использования get_user_model():

  • Гибкость: get_user_model() возвращает текущую модель пользователя проекта, что позволяет изменить модель пользователя, используемую в проекте, без необходимости изменения кода.
  • Портативность: использование get_user_model() позволяет вашему коду быть переносимым между различными проектами Django, где может быть использована различная модель пользователя.
  • Расширяемость: если вы расширяете модель пользователя проекта, например, добавляете новые поля, использование get_user_model() обеспечивает совместимость с этими изменениями, не нарушая стандартных возможностей аутентификации Django.

Кроме того, использование get_user_model() вместо явного импорта модели пользователя упрощает написание тестов, так как тесты не будут зависеть от конкретной модели пользователя.

Также мы применили валидатор FileExtensionValidator для расширений изображений, которые мы разрешаем к загрузке.

Добавление модели в админ-панель

Давайте добавим модель в администравную панель, делается это следующим образом:

Открываем файл blog/admin.py и пишем следующий код:

blog/admin.py
from django.contrib import admin
from .models import Article

admin.site.register(Article)

Теперь мы зарегистрировали нашу модель в админке.

Подключение приложения blog

Далее нам необходимо подключить наше приложение в главном конфиге и провести миграции:

Переходим в файл backend/settings.py и добавляем в INSTALLED_APPS наше приложение:

backend/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'modules.blog.apps.BlogConfig',
]

В следующем уроке мы проведем миграции, добавив модель вложенных категорий!

;