Поиск по сайту:

Как создавать модели Django


Введение

В предыдущем руководстве «Как создать приложение Django и подключить его к базе данных» мы рассмотрели, как создать базу данных MySQL, как создать и запустить приложение Django и как подключить его к базе данных MySQL.

В этом руководстве мы создадим модели Django, которые определяют поля и поведение данных приложения Blog, которые мы будем хранить. Эти модели отображают данные из вашего приложения Django в базу данных. Это то, что Django использует для создания таблиц базы данных с помощью своего API объектно-реляционного сопоставления (ORM), называемого «моделями».

Предпосылки

Это руководство является частью серии Django Development и продолжением этой серии.

Если вы не следили за этой серией, мы делаем следующие предположения:

  • У вас установлена Django версии 4 или выше.
  • Вы подключили приложение Django к базе данных. Мы используем MySQL, и вы можете установить это соединение, следуя второй части серии Django «Как создать приложение Django и подключить его к базе данных».
  • Вы работаете с операционной системой на основе Unix, желательно с облачным сервером Ubuntu 22.04, так как это система, на которой мы тестировали. Если вы хотите настроить Django в аналогичной среде, обратитесь к нашему руководству «Как установить Django и настроить среду разработки в Ubuntu 22.04».

Поскольку это руководство в основном касается моделей Django, вы сможете следовать ему, даже если у вас несколько другая настройка.

Шаг 1 — Создайте приложение Django

Чтобы соответствовать философии модульности Django, мы создадим приложение Django в нашем проекте, содержащее все файлы, необходимые для создания веб-сайта блога.

Всякий раз, когда мы начинаем работать в Python и Django, мы должны активировать нашу виртуальную среду Python и перемещаться в корневой каталог нашего приложения. Если вы следовали этой серии, вы можете добиться этого, набрав следующее.

  1. cd ~/my_blog_app
  2. . env/bin/activate
  3. cd blog

Оттуда запустим эту команду:

  1. python manage.py startapp blogsite

Это создаст наше приложение вместе с каталогом blogsite.

На этом этапе серии руководств у вас будет следующая структура каталогов для вашего проекта:

my_blog_app/
└── blog
    ├── blog
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-38.pyc
    │   │   ├── settings.cpython-38.pyc
    │   │   ├── urls.cpython-38.pyc
    │   │   └── wsgi.cpython-38.pyc
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── blogsite
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    └── manage.py

Файл, на котором мы сосредоточимся в этом руководстве, будет файлом models.py, который находится в каталоге blogsite.

Шаг 2 — Добавьте модель сообщений

Сначала нам нужно открыть и отредактировать файл models.py, чтобы он содержал код для создания модели Post. Модель Post содержит следующие поля базы данных:

  • title — заголовок сообщения в блоге.
  • slug – где хранятся и генерируются допустимые URL-адреса для веб-страниц.
  • content — текстовое содержание сообщения в блоге.
  • created_on — дата создания сообщения.
  • автор — человек, написавший сообщение.

Теперь перейдите в каталог, в котором находится файл models.py.

  1. cd ~/my_blog_app/blog/blogsite

Используйте команду cat, чтобы отобразить содержимое файла в терминале.

  1. cat models.py

Файл должен иметь следующий код, который импортирует модели, а также комментарий, описывающий, что должно быть помещено в этот файл models.py.

from django.db import models

# Create your models here.

Используя ваш любимый текстовый редактор, добавьте следующий код в файл models.py. Мы будем использовать nano в качестве текстового редактора, но вы можете использовать любой другой.

  1. nano models.py

В этом файле уже добавлен код для импорта API моделей, мы можем продолжить и удалить следующий комментарий. Затем мы импортируем slugify для создания слагов из строк, User Django для аутентификации и reverse из django.urls чтобы дать нам большую гибкость при создании URL-адресов.

from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse

Затем добавьте метод класса в класс модели, который мы будем называть Post, со следующими полями базы данных: title, slug, содержание, создано_в и автор. Добавьте их ниже ваших заявлений об импорте.

...
class Post(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, max_length=255)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    author = models.TextField()

Далее мы добавим функционал генерации URL и функцию сохранения поста. Это очень важно, потому что это создает уникальную ссылку, соответствующую нашему уникальному сообщению.

...
    def get_absolute_url(self):
        return reverse('blog_post_detail', args=[self.slug])

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

Теперь нам нужно сообщить модели, как сообщения должны быть упорядочены и отображаться на веб-странице. Логика для этого будет добавлена во вложенный внутренний класс Meta. Класс Meta обычно содержит другую важную логику модели, не связанную с определением поля базы данных.

...
    class Meta:
        ordering = ['created_on']

        def __unicode__(self):
            return self.title

Наконец, мы добавим в этот файл модель Comment. Это включает в себя добавление другого класса с именем Comment с models.Models в его сигнатуре и следующими определенными полями базы данных:

  • name — имя человека, разместившего комментарий.
  • email — адрес электронной почты человека, разместившего комментарий.
  • text — текст самого комментария.
  • post — пост, к которому был сделан комментарий.
  • created_on — время создания комментария.

...
class Comment(models.Model):
    name = models.CharField(max_length=42)
    email = models.EmailField(max_length=75)
    website = models.URLField(max_length=200, null=True, blank=True)
    content = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)

На этом этапе models.py будет готов. Убедитесь, что ваш файл models.py соответствует следующему:

from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse


class Post(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, max_length=255)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    author = models.TextField()

    def get_absolute_url(self):
        return reverse('blog_post_detail', args=[self.slug])
    
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

    class Meta:
        ordering = ['created_on']

        def __unicode__(self):
            return self.title


class Comment(models.Model):
    name = models.CharField(max_length=42)
    email = models.EmailField(max_length=75)
    website = models.URLField(max_length=200, null=True, blank=True)
    content = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)


Обязательно сохраните и закройте файл. Если вы используете nano, вы можете сделать это, набрав CTRL и X, затем Y, затем ENTER .

После настройки файла models.py мы можем обновить наш файл settings.py.

Шаг 3 — Обновить настройки

Теперь, когда мы добавили модели в наше приложение, мы должны сообщить нашему проекту о существовании только что добавленного приложения blogsite. Мы делаем это, добавляя его в раздел INSTALLED_APPS в settings.py.

Перейдите в каталог, где находится ваш файл settings.py.

  1. cd ~/my_blog_app/blog/blog

Отсюда откройте файл settings.py, например, с помощью nano.

  1. nano settings.py

Открыв файл, добавьте свое приложение blogsite в раздел INSTALLED_APPS файла, как показано ниже.

# Application definition
INSTALLED_APPS = [
    'blogsite',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

После добавления приложения blogsite вы можете сохранить файл и выйти из него.

На данный момент мы готовы перейти к применению этих изменений.

Шаг 4 — Сделайте миграцию

После добавления наших моделей Post и Comment следующим шагом будет применение этих изменений, чтобы наша схема базы данных MySQL распознала их и создала необходимые таблицы. .

Во-первых, мы должны упаковать изменения нашей модели в отдельные файлы миграции с помощью команды makemigrations. Эти файлы аналогичны файлам commits в системе контроля версий, такой как Git.

Теперь, если вы перейдете к ~/my_blog_app/blog/blogsite/migrations и запустите ls, вы заметите, что есть только __init__.py файл. Это изменится, как только мы добавим миграции.

Перейдите в каталог блога с помощью cd, например:

  1. cd ~/my_blog_app/blog

Затем запустите команду makemigrations в файле manage.py.

  1. python manage.py makemigrations

Затем вы должны получить следующий вывод в окне терминала:

Output
Migrations for 'blogsite': blogsite/migrations/0001_initial.py - Create model Post - Create model Comment

Помните, когда мы перешли к /~/my_blog_app/blog/blogsite/migrations и там был только файл __init__.py? Если мы теперь cd вернемся в этот каталог, мы заметим, что были добавлены два элемента: __pycache__ и 0001_initial.py. Файл 0001_initial.py был автоматически создан при запуске makemigrations. Подобный файл будет создаваться каждый раз, когда вы запускаете makemigrations.

Запустите less 0001_initial.py из каталога, в котором он находится, если хотите прочитать, что содержится в файле.

Теперь перейдите к ~/my_blog_app/blog:

  1. cd ~/my_blog_app/blog

Поскольку мы создали файл миграции, мы должны применить изменения, описанные в этих файлах, к базе данных с помощью команды migrate. Но сначала давайте проверим, какие миграции уже существуют, с помощью команды showmigrations.

  1. python manage.py showmigrations
Output
admin [X] 0001_initial [X] 0002_logentry_remove_auto_add [X] 0003_logentry_add_action_flag_choices auth [X] 0001_initial [X] 0002_alter_permission_name_max_length [X] 0003_alter_user_email_max_length [X] 0004_alter_user_username_opts [X] 0005_alter_user_last_login_null [X] 0006_require_contenttypes_0002 [X] 0007_alter_validators_add_error_messages [X] 0008_alter_user_username_max_length [X] 0009_alter_user_last_name_max_length [X] 0010_alter_group_name_max_length [X] 0011_update_proxy_permissions blogsite [ ] 0001_initial contenttypes [X] 0001_initial [X] 0002_remove_content_type_name sessions [X] 0001_initial

Вы заметите, что проверяются все миграции, кроме одной для 0001_initial, которую мы только что создали с моделями Post и Comment.

Теперь давайте проверим, какие операторы SQL будут выполняться после выполнения миграции, используя следующую команду. Он принимает миграцию и название миграции в качестве аргумента:

  1. python manage.py sqlmigrate blogsite 0001_initial

Ниже показан фактический SQL-запрос, выполняемый за кулисами.

Output
-- -- Create model Post -- CREATE TABLE `blogsite_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL UNIQUE, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `author` longtext NOT NULL); -- -- Create model Comment -- CREATE TABLE `blogsite_comment` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(42) NOT NULL, `email` varchar(75) NOT NULL, `website` varchar(200) NULL, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `post_id` integer NOT NULL); ALTER TABLE `blogsite_comment` ADD CONSTRAINT `blogsite_comment_post_id_de248bfe_fk_blogsite_post_id` FOREIGN KEY (`post_id`) REFERENCES `blogsite_post` (`id`);

Давайте теперь выполним миграции, чтобы они применялись к нашей базе данных MySQL.

  1. python manage.py migrate

Мы получим следующий вывод:

Output
Operations to perform: Apply all migrations: admin, auth, blogsite, contenttypes, sessions Running migrations: Applying blogsite.0001_initial... OK

Теперь вы успешно применили свои миграции.

Важно иметь в виду, что есть три предостережения относительно миграции Django с MySQL в качестве серверной части, как указано в документации Django.

  • Отсутствие поддержки транзакций вокруг операций изменения схемы. Другими словами, если миграция не может быть успешно применена, вам придется вручную отменить изменения, которые вы сделали, чтобы попытаться выполнить другую миграцию. Невозможно выполнить откат к более ранней точке, до того как в неудачной миграции были внесены какие-либо изменения.
  • Для большинства операций по изменению схемы MySQL полностью перезаписывает таблицы. В худшем случае временная сложность будет пропорциональна количеству строк в таблице для добавления или удаления столбцов. Согласно документации Django, это может занять до одной минуты на миллион строк.
  • В MySQL существуют небольшие ограничения на длину имен для столбцов, таблиц и индексов. Существует также ограничение на общий размер всех столбцов и обложек индексов. В то время как некоторые другие бэкенды могут поддерживать более высокие ограничения, созданные в Django, те же самые индексы не будут созданы с бэкэндом MySQL.

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

Шаг 5 — Проверка схемы базы данных

После завершения миграции мы должны проверить успешное создание таблиц MySQL, которые мы создали с помощью наших моделей Django.

Для этого выполните следующую команду в терминале, чтобы войти в MySQL. Мы будем использовать djangouser, созданный в предыдущем уроке.

  1. mysql blog_data -u djangouser

Теперь выберите нашу базу данных blog_data. Если вы не знаете, какую базу данных используете, вы можете отобразить все базы данных с помощью SHOW DATABASES; в SQL.

  1. USE blog_data;

Затем введите следующую команду для просмотра таблиц.

  1. SHOW TABLES;

Этот SQL-запрос должен показать следующее:

Output
+----------------------------+ | Tables_in_blog_data | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | blogsite_comment | | blogsite_post | | django_admin_log | | django_content_type | | django_migrations | | django_session | +----------------------------+ 12 rows in set (0.01 sec)

Среди таблиц есть blogsite_comment и blogsite_post. Это модели, которые мы только что сделали сами. Давайте проверим, что они содержат поля, которые мы определили.

  1. DESCRIBE blogsite_comment;
Output
+------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | name | varchar(42) | NO | | NULL | | | email | varchar(75) | NO | | NULL | | | website | varchar(200) | YES | | NULL | | | content | longtext | NO | | NULL | | | created_on | datetime(6) | NO | | NULL | | | post_id | int | NO | MUL | NULL | | +------------+--------------+------+-----+---------+----------------+ 7 rows in set (0.00 sec)
  1. DESCRIBE blogsite_post;
Output
+------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | title | varchar(255) | NO | | NULL | | | slug | varchar(255) | NO | UNI | NULL | | | content | longtext | NO | | NULL | | | created_on | datetime(6) | NO | | NULL | | | author | longtext | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 6 rows in set (0.00 sec)

Мы убедились, что таблицы базы данных были успешно сгенерированы в результате миграции модели Django.

Вы можете выйти из MySQL с помощью CTRL + D, а когда вы будете готовы покинуть среду Python, вы можете запустить команду deactivate:

  1. deactivate

Деактивация вашей среды программирования вернет вас к командной строке терминала.

Заключение

В этом руководстве мы успешно добавили модели для базовой функциональности веб-приложения блога. Вы узнали, как кодировать модели, как работают миграции и процесс перевода моделей Django в настоящий MySQL. таблицы базы данных.