Что делает команда `makemigrations` в Django?

Ответ

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

Подробный процесс:

  1. Сканирование моделей: Django сканирует все файлы models.py в установленных приложениях проекта, чтобы получить текущее состояние всех моделей (классов, унаследованных от django.db.models.Model).
  2. Сравнение с историей миграций: Он сравнивает текущее состояние моделей с их состоянием, зафиксированным в последней примененной миграции для каждого приложения (или с начальным состоянием, если миграций нет). Django использует внутренний механизм для отслеживания изменений в полях, метаданных и отношениях моделей.
  3. Обнаружение изменений: Если обнаружены различия (например, добавление нового поля, изменение типа поля, удаление модели, изменение отношений), Django определяет необходимые операции для приведения схемы базы данных в соответствие с новыми моделями.
    • Примеры операций: CreateModel (создание таблицы), AddField (добавление столбца), AlterField (изменение столбца), DeleteModel (удаление таблицы).
  4. Генерация файла миграции: Создается новый Python-файл в директории migrations/ соответствующего приложения (например, 000X_auto_YYYYMMDD_HHMM.py). Этот файл содержит класс Migration с атрибутом operations, который перечисляет обнаруженные изменения в виде Python-кода.

    # Пример содержимого файла миграции
    from django.db import migrations, models
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('myapp', '0001_initial'), # Зависимость от предыдущей миграции
        ]
    
        operations = [
            migrations.AddField(
                model_name='user',
                name='age',
                field=models.IntegerField(default=0),
            ),
        ]
  5. Вывод информации: В консоль выводится информация о созданных миграциях и обнаруженных изменениях, например: Migrations for 'myapp': myapp/migrations/0002_add_age_to_user.py.

Важно: Команда makemigrations только генерирует файлы миграций. Она не вносит никаких изменений в базу данных. Для применения этих изменений к базе данных необходимо выполнить команду python manage.py migrate.

Ответ 18+ 🔞

А, ну это же классика, блядь! Сидишь ты такой, накодил новое поле в модель, а потом думаешь: "И какого хуя база данных об этом узнает?" Вот тут-то и вступает в игру наш верный друг — makemigrations, ёпта!

Представь себе, что Django — это такой дотошный архитектор, который ведёт журнал всех изменений в твоём проекте. А makemigrations — это момент, когда ты ему докладываешь: "Слушай, архитектор, я тут стенку передвинул и окно новое врезал".

Что он делает по шагам, этот хитрожопый скрипт:

  1. Рыщет по всем закоулкам. Он лезет во все твои models.py и смотрит, что ты там наваял. Все эти классы, которые от Model унаследованы — его пища, блядь.
  2. Сверяется с историей. Потом он идёт в папочку migrations и смотрит, а что же было в последний раз, когда он тут составлял планы? Он сравнивает, что ты хочешь сейчас, с тем, что было зафиксировано в прошлой миграции.
  3. Находит разницу и офигевает. "О, хули тут у нас? А, так ты, сука, поле age к модели User добавил? А тип CharField на TextField поменял? Ну ты даёшь, пидарас шерстяной!" Он всё это замечает.
  4. Пишет новый "приказ". Он не лезет в базу данных сломя голову. Нет, он создаёт новый файлик в той же папке migrations (типа 0002_add_age_to_user.py). И в этом файле чётко, по пунктам, расписывает, что нужно сделать: "Операция номер раз — добавить поле age в таблицу user".

    # Вот примерно что он там накарябывает
    from django.db import migrations, models
    
    class Migration(migrations.Migration):
        dependencies = [
            ('myapp', '0001_initial'), # Чтоб не забыть, с чего начали
        ]
        operations = [
            migrations.AddField( # Собственно, приказ
                model_name='user',
                name='age',
                field=models.IntegerField(default=0),
            ),
        ]
  5. Хвастается. И в конце такой: "Всё, мудак, я работу сделал. Смотри, что я сгенерил: Migrations for 'myapp': myapp/migrations/0002_add_age_to_user.py".

И вот тут главное, блядь, не обосраться! makemigrations только ПИШЕТ план. Он НЕ ТРОГАЕТ базу данных ни на йоту. Это как нарисовать чертёж новой пристройки.

Чтобы этот чертёж воплотить в жизнь, надо уже другую команду запустить — python manage.py migrate. Вот она-то возьмёт этот свеженький файл с планом и пойдёт в базу данных всё это дело внедрять. А если migrate не запустить, то так и будешь жить с чертежами, а в реальности у тебя стена на старом месте будет стоять. Пиздец, да?