Миграции отражают не только базу данных, но и некоторую бизнес-логику. Миграции взрываются

Предположим, что у нас есть модель (пример взят из документации https://docs.djangoproject.com/en/4.1/ref/models/fields/#filefield):

def user_directory_path(instance, filename):
    # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
    return 'user_{0}/{1}'.format(instance.user.id, filename)

class MyModel(models.Model):
    upload = models.FileField(upload_to=user_directory_path)

Миграции будут выглядеть следующим образом:

('upload', models.FileField(upload_to=vocabulary_phrases.models.user_directory_path)),

Но теперь вы решили перейти в класс:

class UploadTo:
    def __init__(self, folder, filename_suffix=""):
        self.folder = folder
        self.filename_suffix = filename_suffix

    def _get_filename(self, instance, filename):
        _, file_extension = os.path.splitext(filename)
        result = str(instance.a_uuid)

        if self.filename_suffix:
            result += "-{}".format(self.filename_suffix)

        result += file_extension

        return result

    def save_path(self, instance, filename):
        tmp_filename = self._get_filename(instance, filename)
        result = "{}/{}".format(self.folder.value,
                                tmp_filename)
        return result


class MyModel(models.Model):
    upload = UploadTo(folder=UPLOAD_TO.VOCABULARY_FILE_FOLDER, filename_suffix="trololo").save_path

Когда вы пытаетесь сделать миграции, этот код вылетает. Он будет жаловаться как 0002_migration contains user_directory_path, it is absent.

Это изменение в коде не механическое. Я не могу представить, что это может быть сделано просто рефактором / переименованием в IDE. Тогда я не могу представить, как должна выглядеть новая миграция. Это означает, что я не смогу легко изменить файл миграций.

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

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

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

Могли бы вы порекомендовать мне, как лучше всего справиться с этой проблемой?

Простым решением было бы запустить

python manage.py makemigrations

пока у вас еще есть user_directory_path в вашем файле

eg:

import os

from django.db import models


def user_directory_path(instance, filename):
    # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
    return "user_{0}/{1}".format(instance.user.id, filename)


class UploadTo:
    def __init__(self, folder, filename_suffix=""):
        self.folder = folder
        self.filename_suffix = filename_suffix

    def _get_filename(self, instance, filename):
        _, file_extension = os.path.splitext(filename)
        result = str(instance.a_uuid)

        if self.filename_suffix:
            result += "-{}".format(self.filename_suffix)

        result += file_extension

        return result

    def save_path(self, instance, filename):
        tmp_filename = self._get_filename(instance, filename)
        result = "{}/{}".format(self.folder.value, tmp_filename)
        return result


class UPLOAD_TO:
    VOCABULARY_FILE_FOLDER = "asd"


class MyModel(models.Model):
    upload = UploadTo(
        folder=UPLOAD_TO.VOCABULARY_FILE_FOLDER, filename_suffix="trololo"
    ).save_path

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

Вернуться на верх