Создание сайта на Django: Урок 3, создание модели «Статьи»
avatar
7 | (offline)
❤️‍🔥Notehunter Developer
Добавлено:
Категория: Руководства «Django»
Комментариев: 6

Как мы видим из прошлого урока, у нас в папке "Блог" есть следующие файлы: 

  • migrations (папка)
  • __init__.py
  • admin.py (нужен этот)
  • apps.py
  • models.py (нужен этот)
  • tests.py
  • views.py

Создание модели статьи для блога на Django

И так, заходим в редактирование models.py, и давайте добавим нашу первую модель. Но первое, что мы сделаем, это установим необходимые зависимости для изображений (превью) и конечно для категорий, так как я хочу использовать вложенные категории в виде дерева. 

В терминале вводим и устанавливаем следующие зависимости:

pip install Pillow django-mptt
  • Pillow отвечает за работу с изображениями, если прочитать документацию, в ней очень много чего интересного.
  • Django-mptt отвечает за создание моделей в виде иерархии, дерева. Например, категория: Программирование -> Python -> Django. Все здесь вложено.

В терминале должно выдать следующее:

(venv) PS C:\Users\Razilator\Desktop\Courses\App\backend> pip install django-mptt Pillow
Collecting django-mptt
Installing collected packages: Pillow, django-js-asset, django-mptt
Successfully installed Pillow-9.2.0 django-js-asset-2.0.0 django-mptt-0.13.4

Заранее подключим Django-mptt в INSTALLED_APPS в файле 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',
    'mptt',
]

После установки добавим нашу модель Article (Статьи), пока без категорий в models.py

from django.contrib.auth.models import User
from django.core.validators import FileExtensionValidator
from django.db import models


class Article(models.Model):
	"""
	Модель статей для проекта
	"""
	title = models.CharField(verbose_name='Заголовок', max_length=255)
    slug = models.SlugField(verbose_name='URL', max_length=255, blank=True)
    short_description = models.TextField(max_length=300, verbose_name='Краткое описание')
    full_description = models.TextField(verbose_name='Описание')
    author = models.ForeignKey(User, verbose_name='Автор материала', on_delete=models.PROTECT, related_name='article_author')
    updated_by = models.ForeignKey(User, verbose_name='Автор обновления', on_delete=models.CASCADE, related_name='article_updated_by', blank=True, null=True)
    created_at = models.DateTimeField(verbose_name='Дата добавления', auto_now_add=True, db_index=True)
    updated_at = models.DateTimeField(verbose_name='Дата обновления', auto_now=True, db_index=True)
    reason = models.CharField(verbose_name='Причина обновления', blank=True, max_length=100)
    is_fixed = models.BooleanField(verbose_name='Зафиксировано', default=False, db_index=True)
    is_published = models.BooleanField(verbose_name='Опубликовано', default=True)
    thumbnail = models.ImageField(
        verbose_name='Превью поста',
        blank=True,
        upload_to='images/thumbnails/',
        validators=[FileExtensionValidator(
            allowed_extensions=('png', 'jpg', 'webp', 'jpeg', 'gif'))
        ]
    )
    
    class Meta:
        """
        Сортировка, название модели в админ панели, таблица в данными
        """
        ordering = ('-is_fixed', '-created_at')
        verbose_name = 'Статья'
        verbose_name_plural = 'Статьи'
        db_table = 'app_articles'

    def __str__(self):
        """
        Возвращение строки в виде заголовка статьи
        """
        return self.title

Пояснения за поля:

  • title - заголовок, с максимальным количеством символов 255
  • slug - ссылка на материал (латиница), с максимальным количеством символов 255, blank (необязательно к заполнению)
  • short_description - текстовое поле, ограниченное 300 символами. 
  • full_description - аналогично, без ограничений.
  • author - ключ ссылаемый на пользователя из другой таблицы (пользователей) c on_delete=models.PROTECT (при удалении происходит защита, что не позволяет так просто удалить пользователя с его статьями, чтоб вы могли передать статьи другому человеку)
  • updated_by - аналогично, только если при обновлении статьи выводить того, кто редактировал (добавлять, если вам это нужно) c on_delete=models.CASCADE (при удалении просто убирается значение того, кто обновил у статей каскадно)
  • reason - причина редактирования
  • is_fixed - булево значение, по умолчанию False (зафиксировано)
  • is_published - булево значение, по умолчанию True (опубликовано)

Также добавлены db_index=True к полям, которые используются в сортировке.

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

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

Подключение Django модели в Административную модель

Открываем файл admin.py и вставляем следующее содержимое

from django.contrib import admin
from modules.blog.models import Article

admin.site.register(Article)

Миграция модели в базу данных Django

И так, предпоследний шаг для появлений рабочей модели: мы должны создать миграции и применить их, делается это следующим образом:

python manage.py makemigrations
python manage.py migrate

Если все сделали верно, то в консоли будет следующее содержимое:

(venv) PS C:\Users\Razilator\Desktop\Courses\App\backend> python manage.py makemigrations
Migrations for 'blog':
  modules\blog\migrations\0001_initial.py
    - Create model Article
(venv) PS C:\Users\Razilator\Desktop\Courses\App\backend> python manage.py migrate       
Operations to perform:
  Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying blog.0001_initial... OK
  Applying sessions.0001_initial... OK
(venv) PS C:\Users\Razilator\Desktop\Courses\App\backend> 

Теперь нам нужно создать суперпользователя для доступа к админ.панели!

Создание суперпользователя в Django

Для этого мы выполняем следующую команду:

python manage.py createsuperuser

Задаем логин, email и пароль.

Давайте зайдем в панель управления и увидим нашу добавленную модель. Логинимся через только что созданного суперпользователя и видимо следующее:

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

Комментарии к статье 6
  • tipa_dev
    15 марта 2023 г. 18:04

    в этой строке почему-то ошибка: from modules.blog.models import Article

    импортировал так: from .models import Article

    • Razilator
      16 марта 2023 г. 15:09

      tipa_dev, да, можно так, зависит от расположения папок, и файла init.py. Я на курсе по Django 2023 на другом сайте уже также импортирую)

      • qulok99
        10 мая 2023 г. 9:42

        Razilator, а что за курс и где можно посмотреть?

        • Razilator
          11 мая 2023 г. 12:11

          qulok99, почти аналогичный существующему, только грамотнее, код немного другой, и в 50 уроков уместил больше информации, и тоже мой. Держите proghunter.ru. Это мой новый сайт, он сделан на двух технологиях, Django + Next.js, он работает намного быстрее, и вскоре notehunter мне придется закрыть, ибо не повезло с доменом, его плохо кушают боты, а гугл вообще дал бан из-за своего обновления. И посещаемость там уже на 500 больше.

          • qulok99
            11 мая 2023 г. 12:43

            Razilator, спасибо, главное не сдавайтесь, у вас достойный контент и сайты тоже

            • Razilator
              11 мая 2023 г. 16:30

              qulok99, спасибо. Да видите, с этим notehunter.net не повезло, зато с прогхантером повезло, там будет весь контент, поэтому лучше туда переходите и в группу телеграмм, в которой скоро организую чат.

Форма добавления комментария (необходима регистрация)