Django - невозможно удалить строки при миграции назад
У меня возникла проблема. Я реализовал миграцию для создания еще одной опции в моей модели (добавить текстовый выбор preview
) и реализовал метод RunPython для создания строк в таблице, которая соответствует моим требованиям. Это работает.
Часть, которая не работает, - это обратный код. Я просто запрашиваю и фильтрую экземпляры, которые я хочу удалить, и пытаюсь их удалить. При этом я получаю эту странную ошибку:
Эта ошибка не имеет смысла. Есть ли у кого-нибудь предположение, что это может быть?
Код миграции:
from django.db import migrations, models
def converter(apps, schema_editor):
AppExtension = apps.get_model("applications", "AppExtension")
MediaType = apps.get_model("applications", "MediaType")
MediaSize = apps.get_model("applications", "MediaSize")
all_extensions = AppExtension.objects.all()
media_types = []
media_sizes = []
for extension in all_extensions:
mediatype_extension = MediaType(extension=extension, name="preview")
media_types.append(mediatype_extension)
media_sizes.append(
MediaSize(
media_type=mediatype_extension,
name="intrinsic",
width=1920,
height=960,
)
)
media_sizes.append(
MediaSize(
media_type=mediatype_extension,
name="optimized",
width=960,
height=480,
)
)
MediaType.objects.bulk_create(media_types)
MediaSize.objects.bulk_create(media_sizes)
def reverter(apps, schema_editor):
MediaType = apps.get_model("applications", "MediaType")
all_extensions = AppExtension.objects.all()
MediaType.objects.filter(
name="preview",
).delete()
class Migration(migrations.Migration):
dependencies = [
("applications", "0011_alter_mediatype_name"),
]
operations = [
migrations.AlterField(
model_name="mediatype",
name="name",
field=models.CharField(
choices=[
("thumbnail", "Thumbnail"),
("icon", "Icon"),
("app-icon", "App Icon"),
("preview", "Preview"),
],
default="thumbnail",
help_text="Name of this media type",
max_length=32,
verbose_name="Name",
),
),
migrations.RunPython(converter, reverse_code=reverter),
]
Мои модели:
class MediaType(UUIDModel):
class TypeChoices(models.TextChoices):
THUMBNAIL = "thumbnail", "Thumbnail"
ICON = "icon", "Icon"
APP_ICON = "app-icon", "App Icon"
PREVIEW = "preview", "Preview"
extension = models.ForeignKey(
AppExtension,
on_delete=models.CASCADE,
related_name="media_types",
verbose_name=_("AppExtension"),
help_text="AppExtension this MediaType belongs to",
)
name = models.CharField(
max_length=32,
verbose_name=_("Name"),
help_text=f"Name of this media type",
choices=TypeChoices.choices,
default=TypeChoices.THUMBNAIL,
)
@property
def sizes_dict(self) -> dict:
if self.sizes.exist():
return {size.name: size.get_tuple() for size in self.sizes.all()}
return {}
def __str__(self) -> str:
return f"{self.extension.name} - {self.name}"
class Meta:
constraints = [
UniqueConstraint(
fields=["extension", "name"],
name="unique_media_type_name_per_extension",
),
]
class MediaSize(UUIDModel):
class SizeChoices(models.TextChoices):
INTRINSIC = "intrinsic", "Intrinsic"
OPTIMIZED = "optimized", "Optimized"
media_type = models.ForeignKey(
MediaType,
on_delete=models.CASCADE,
verbose_name=_("Media Type"),
help_text="Media type this size reffers to",
related_name="sizes",
)
name = models.CharField(
max_length=32,
verbose_name=_("Name"),
help_text=f"Name of this media size",
choices=SizeChoices.choices,
default=SizeChoices.INTRINSIC,
)
width = models.PositiveIntegerField(
verbose_name=_("Width"),
help_text="Width of this media size",
)
height = models.PositiveIntegerField(
verbose_name=_("Height"),
help_text="Height of this media size",
)
def get_tuple(self) -> Tuple[int, int]:
return self.width, self.height
def __str__(self) -> str:
return (
f"{self.media_type.extension.name} - {self.media_type.name}"
+ f" - {self.name}: ({self.get_tuple()})"
)
class Meta:
constraints = [
UniqueConstraint(
fields=["media_type", "name"],
name="unique_media_size_name_per_media_type",
),
UniqueConstraint(
fields=["media_type", "height", "width"],
name="unique_media_size_dimensions_per_media_type",
),
]
- Попробовал выполнить точно такой же код для удаления строк вне миграции -> работает .
- Попробовал остановить миграцию между ними, получить единственный экземпляр вложенного типа
MediaSize
и удалить его -> выдает ту же ошибку - Запуск миграции с отладчиком vscode и без него приводит к той же ошибке .
- Во время миграции можно обновлять и сохранять экземпляр, только операция удаления вызывает эту ошибку .
Попробуйте просто удалить reverse_code. Я не думаю, что он вам нужен, поскольку операция не нуждается в реверсировании.