TLDR: Ошибка получения: LookupError: No installed app with label 'wagtailimages'.
после выполнения пользовательской миграции данных в трясогузке, что приводит к сбою всех тестов, поскольку Django не может найти приложение после запуска последней миграции.
I Мне нужно было добавить несколько пользовательских полей в мою модель изображения в моей установке трясогузки, которая поддерживает Vue SPA.
Я следовал инструкциям в документации здесь: http://docs.wagtail.io/en/v2.0/advanced_topics/images/custom_image_model.html
Итак, я создал пользовательскую модель изображения вместе с пользовательским воспроизведением, например так:
class CustomImage(AbstractImage):
alt_text = models.CharField(max_length=255, blank=True)
caption = models.CharField(max_length=255, blank=True)
admin_form_fields = Image.admin_form_fields + (
"alt_text",
"caption",
)
class CustomRendition(AbstractRendition):
image = models.ForeignKey(
CustomImage, on_delete=models.CASCADE, related_name="renditions"
)
class Meta:
unique_together = (
("image", "filter_spec", "focal_point_key"),
)
Я также изменил настройку WAGTAILIMAGES_IMAGE_MODEL
, чтобы она указала на мою новую модель:
WAGTAILIMAGES_IMAGE_MODEL = "pages.CustomImage"
Я написал миграцию данных с помощью этого сообщения в блоге , которое ссылается на это обсуждение StackOverflow :
# Generated by Django 2.1.10 on 2020-01-15 09:03
from django.db import migrations, models
def forwards_func(apps, schema_editor):
wagtail_image_model = apps.get_model("wagtailimages", "Image")
custom_image_model = apps.get_model("pages", "CustomImage")
tagged_item_model = apps.get_model("taggit", "TaggedItem")
django_content_type = apps.get_model("contenttypes", "contenttype")
db_alias = schema_editor.connection.alias
# Get images stored in default wagtail image model
images = wagtail_image_model.objects.using(db_alias).all()
new_images = []
for image in images:
new_images.append(
custom_image_model(
id=image.id,
title=image.title,
file=image.file,
width=image.width,
height=image.height,
created_at=image.created_at,
focal_point_x=image.focal_point_x,
focal_point_y=image.focal_point_y,
focal_point_width=image.focal_point_width,
focal_point_height=image.focal_point_height,
file_size=image.file_size,
collection=image.collection,
uploaded_by_user=image.uploaded_by_user,
)
)
# Create images in new model
custom_image_model.objects.using(db_alias).bulk_create(new_images)
# Leave all images in previous model untouched.
# Move tags from old image to new image model. Moving tags is
# a little different case. The lookup table taggit_taggeditem looks like this:
# id object_id content_type_id tag_id
# 1 1 10 1
# 2 1 10 2
# 3 1 10 3
# 4 1 10 4
# In our case, the object_id will be same for old and new image model
# objects. So, we have to only change the content_type_id
ct_custom_img_model, created = django_content_type.objects.using(
db_alias
).get_or_create(app_label="pages", model="customimage")
ct_wagtail_model = django_content_type.objects.using(db_alias).get(
app_label="wagtailimages", model="image"
)
tagged_item_model.objects.using(db_alias).filter(
content_type_id=ct_wagtail_model.id
).update(content_type_id=ct_custom_img_model.id)
def reverse_func(apps, schema_editor):
# We get the model from the versioned app registry;
custom_image_model = apps.get_model("pages", "CustomImage")
tagged_item_model = apps.get_model("taggit", "TaggedItem")
django_content_type = apps.get_model("contenttypes", "contenttype")
db_alias = schema_editor.connection.alias
# Move tags from new image model to old wagtail model
ct_extended_model = django_content_type.objects.using(db_alias).get(
app_label="pages", model="customimage"
)
ct_wagtail_model = django_content_type.objects.using(db_alias).get(
app_label="wagtailimages", model="image"
)
tagged_item_model.objects.using(db_alias).filter(
content_type_id=ct_extended_model.id
).update(content_type_id=ct_wagtail_model.id)
# Delete all images created in the new model
custom_image_model.objects.using(db_alias).all().delete()
class Migration(migrations.Migration):
dependencies = [
("pages", "0030_auto_20200115_0817"),
]
operations = [
migrations.RunPython(forwards_func, reverse_func),
]
Прямая миграция работает, как ожидается, для миграции всех данные и работают хорошо, когда я тестировал эти изменения локально.
Я пытался проверить мою обратную миграцию, и они также работают нормально.
Однако, если я пытаюсь получить старую wagtailimages.Image
модель в моей функции reverse_func
, она выдает ошибку или LookupError: No installed app with label 'wagtailimages'.
Хотя на самом деле я хотел удалить изображения из старой модели просто для очистки, но из-за этой ошибки я подумал, что это не так важно, и я могу просто двигаться дальше.
К сожалению, как только я отправил код в CI, все мои тесты провалились, так как, когда применяется эта 31-я миграция, которая является переносом пользовательских данных, Django, похоже, вообще не находит приложение wagtailimages
.
Я не уверен, в чем здесь проблема. Я пытался отладить эту проблему некоторое время, но все мои усилия оказались тщетными. Я также не нашел ничего связанного с этим в Интернете, что могло бы помочь.
Я также попытался упростить мою миграцию, например, вообще ничего не делать и просто пытаться получить модель, используя Django х apps.get_model
Прямая миграция работает нормально, но при обратной миграции приложение wagtailimages
просто исчезает. Я не уверен, почему django.setup()
не может загрузить это приложение.
Может кто-нибудь помочь в этом вопросе и дать мне указатель на то, что происходит в сторону?