Миграции отражают не только базу данных, но и некоторую бизнес-логику. Миграции взрываются
Предположим, что у нас есть модель (пример взят из документации 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
тогда вы можете сбросить миграции и удалить функцию, что позволит избежать необходимости развертывать копию проекта