JavaRush /Курсы /Модуль 3: Django /Создание миграций для изменений моделей

Создание миграций для изменений моделей

Модуль 3: Django
7 уровень , 8 лекция
Открыта

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

Сегодня мы научимся:

  • Как вносить изменения в существующие модели.
  • Как создавать миграции для изменений.
  • Как применять эти миграции к базе данных.

Изменения в структурах моделей

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

Пример: добавление нового поля

Допустим, у нас есть модель Book, которая изначально выглядит вот так:

# models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    published_date = models.DateField()

После запуска первоначальной миграции и применения её к базе данных, эту структуру мы уже "запечатали". Однако, через месяц к вам приходит клиент и просит добавить поле ISBN для учёта номеров книг. Вот что нужно сделать:

  1. Открыть файл models.py и добавить новое поле.

    # models.py
    class Book(models.Model):
        title = models.CharField(max_length=200)
        author = models.CharField(max_length=100)
        published_date = models.DateField()
        isbn = models.CharField(max_length=13, null=True, blank=True)  # Новое поле
  2. Создать миграцию для этого изменения:

    python manage.py makemigrations
    
  3. Django проанализирует изменения в модели Book и создаст миграционный файл, добавляющий новое поле isbn в таблицу.

  4. Применить миграцию:

    python manage.py migrate
    

Что произойдет в базе данных?

Django создаст SQL-команду для добавления нового столбца в таблицу Book. Поскольку мы указали null=True и blank=True, база данных не будет требовать обязательного заполнения этого поля для уже существующих записей.

Изменение существующих полей

Теперь предположим, что клиент решил, что 13 символов для ISBN не всегда достаточно, и теперь длина поля должна быть 20 символов. Вот как мы это сделаем:

  1. Откройте models.py и измените атрибут max_length для поля isbn:

    class Book(models.Model):
        title = models.CharField(max_length=200)
        author = models.CharField(max_length=100)
        published_date = models.DateField()
        isbn = models.CharField(max_length=20, null=True, blank=True)  # Изменение длины
    
  2. Создайте миграцию:

    python manage.py makemigrations
    
  3. Примените изменения:

    python manage.py migrate
    

Django сгенерирует SQL-запрос, который изменяет длину столбца isbn в базе данных.

Удаление полей

Иногда приходится удалять существующие поля. Давайте удалим поле published_date (но помните, что такие изменения могут привести к потере данных!).

  1. Удалите поле из модели:

    class Book(models.Model):
        title = models.CharField(max_length=200)
        author = models.CharField(max_length=100)
        isbn = models.CharField(max_length=20, null=True, blank=True)
    
  2. Создайте миграцию:

    python manage.py makemigrations
    
  3. Примените миграцию:

    python manage.py migrate
    

Django удалит столбец published_date из таблицы Book. Перед этим убедитесь, что вы бэкапите данные из этого столбца, если они вам понадобятся!

Переименование полей

Если нужно сменить имя поля (например, из isbn в isbn_code), используйте всё тот же механизм:

  1. Переименуйте поле в модели:

    class Book(models.Model):
        title = models.CharField(max_length=200)
        author = models.CharField(max_length=100)
        isbn_code = models.CharField(max_length=20, null=True, blank=True)  # Новое имя
    
  2. Создайте миграцию:

    python manage.py makemigrations
    
  3. Примените миграцию:

    python manage.py migrate
    

Сложные изменения: объединение или разделение таблиц

Иногда нужно разделить одну таблицу (модель) на две или, наоборот, объединить несколько моделей в одну. Это сложный процесс, который, как правило, требует ручного вмешательства. Django создаёт миграции, но может также потребоваться написать SQL-запросы вручную.

Как работает Django при создании миграций?

Миграции в Django работают на принципе отслеживания изменений в вашей модели. Когда вы вызываете manage.py makemigrations, Django сравнивает текущую версию моделей с последней миграцией, которая была применена ранее. Затем он генерирует новый миграционный файл на основе этого изменения.

Миграционный файл выглядит как Python-скрипт и обычно находится в папке приложения migrations. Вы можете открыть его и увидеть что-то подобное:

# Пример миграционного файла (auto-generated)
from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('books', '0001_initial'),  # Зависимость от предыдущей миграции
    ]

    operations = [
        migrations.AddField(
            model_name='book',
            name='isbn',
            field=models.CharField(blank=True, max_length=13, null=True),
        ),
    ]

Типичные ошибки и как их избежать

Ошибки случаются, когда:

  1. Вы забыли применить миграцию. Если после makemigrations вы не выполните migrate, база данных останется в старом состоянии. Обязательно применяйте миграции!

  2. Изменения несовместимы. Например, вы решили удалить поле, которое было обязательным (null=False), — это вызовет проблемы, если в таблице уже есть записи. Обязательно добавляйте default или null=True перед такими изменениями.

  3. Вы меняете поле, которое связано с ForeignKey. При изменении связанных таблиц используйте осторожные подходы, помня про связанные записи.

  4. Вы случайно изменили уже применённую миграцию. Никогда не редактируйте ранее автоматически созданные миграции. Это может сломать всю последовательность изменений базы данных.

Практическое задание

  1. Создайте модель Author с полями name (строка длиной до 100 символов) и birth_date (дата). Проведите миграцию.
  2. Добавьте в модель Author поле nationality (строка длиной до 50 символов). Проведите миграцию для этих изменений.
  3. Удалите поле birth_date и проведите очередную миграцию.
  4. Взаимодействуйте с моделью через Django shell, запишите несколько авторов в базу и проверьте их поля.

Вуаля, теперь вы готовы смело изменять структуры своих моделей и управлять ими через миграции. Уверен, что ваш клиент оценит гибкость, с которой вы можете отвечать на его изменения требований!

1
Задача
Модуль 3: Django, 7 уровень, 8 лекция
Недоступна
Изменение типа существующего поля
Изменение типа существующего поля
1
Задача
Модуль 3: Django, 7 уровень, 8 лекция
Недоступна
Объединение полей через миграцию
Объединение полей через миграцию
Комментарии (4)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Марат Уровень 56
19 ноября 2025
Как уже эти танцы с валидатором достали. И за это я деньги платил?!😤
Муса Романюк Уровень 66
7 октября 2025
Вторая задача такая гонимая, даже скопированное правильное решение не принимает. После танцев с бубном кое-как решил, добавив solution.sh.
Евгений Уровень 81
22 августа 2025
В 1ой задаче (Изменение типа существующего поля)
3. Измените в модели `Book` тип поля `title` с `CharField` на `TextField`.
на свою голову при изменении типа поля решил оставить атрибут max_length, т.к. в предыдущих лекциях упоминалось, что он используется для CharField и TextField. Как результат, задача не проходит валидацию, а валидатор не может объяснить в чем проблема. Во 2ой задаче в settings.py отсутствует настройка: DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' из-за чего при попытке создания миграции система выдаст ошибку. А дальше берем тот же ChatGPT и разбираемся как работать с пользовательскими миграциями ))
Ivan Уровень 59
24 июля 2025
Как обычно, сначала создаём базу данных, а потом удаляем иначе задание не зачтут.