Как исправить ошибку при обновлении Wagtail 2.10.2 до 2.11.8?

#django #wagtail

Вопрос:

Я обновил версию Wagtail v1.13 / Django v1.11 / Python 3.5.2, чтобы обновить проект.

Все прошло гладко, теперь я нахожусь в Wagtail 2.10.2 / Django 3.0.14 / Python 3.8.9

Проект использует puput, поэтому не может выйти за рамки Django 3.0.14, пока puput не поддержит более новую версию Django. Это не проблема, пока я этим доволен.

Однако после установки Wagtail 2.11.8, когда я запускаю makemigrations, я получаю следующую ошибку:

 AttributeError: module 'wagtail.core.models' has no attribute 'MultiTableCopyMixin'
 

Комбинация Трясогузка 2.10.2/Джанго 3.0.14 создана 0038_auto_20210624_0634.py который содержит следующую строку:

 bases=(wagtail.core.models.MultiTableCopyMixin, models.Model),
 

Конечно, в моделях Wagtail 2.10.2 wagtail.core..Мультитаблекопимиксин существует, но в трясогузке 2.11.* Мультитаблекопимиксин удален.

Я также пытался сохранить Django в версии 2.2.24, но все равно получаю ту же проблему.

Есть какие-нибудь идеи?

Полное содержимое автоматически сгенерированной миграции ниже см. 2-ю запись в массиве операций:

 # Generated by Django 2.2.24 on 2021-06-24 14:07

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import modelcluster.fields
import wagtail.core.models


class Migration(migrations.Migration):

    dependencies = [
        ('contenttypes', '0002_remove_content_type_name'),
        ('auth', '0011_update_proxy_permissions'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('wagtailcore', '0037_auto_20210624_0316'),
    ]

    operations = [
        migrations.CreateModel(
            name='Task',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=255, verbose_name='name')),
                ('active', models.BooleanField(default=True, help_text='Active tasks can be added to workflows. Deactivating a task does not remove it from existing workflows.', verbose_name='active')),
                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='wagtail_tasks', to='contenttypes.ContentType', verbose_name='content type')),
            ],
            options={
                'verbose_name': 'task',
                'verbose_name_plural': 'tasks',
            },
        ),
        migrations.CreateModel(
            name='TaskState',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('status', models.CharField(choices=[('in_progress', 'In progress'), ('approved', 'Approved'), ('rejected', 'Rejected'), ('skipped', 'Skipped'), ('cancelled', 'Cancelled')], default='in_progress', max_length=50, verbose_name='status')),
                ('started_at', models.DateTimeField(auto_now_add=True, verbose_name='started at')),
                ('finished_at', models.DateTimeField(blank=True, null=True, verbose_name='finished at')),
                ('comment', models.TextField(blank=True)),
                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='wagtail_task_states', to='contenttypes.ContentType', verbose_name='content type')),
                ('finished_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='finished_task_states', to=settings.AUTH_USER_MODEL, verbose_name='finished by')),
                ('page_revision', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='task_states', to='wagtailcore.PageRevision', verbose_name='page revision')),
                ('task', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='task_states', to='wagtailcore.Task', verbose_name='task')),
            ],
            options={
                'verbose_name': 'Task state',
                'verbose_name_plural': 'Task states',
            },
            bases=(wagtail.core.models.MultiTableCopyMixin, models.Model),
        ),
        migrations.CreateModel(
            name='Workflow',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=255, verbose_name='name')),
                ('active', models.BooleanField(default=True, help_text='Active workflows can be added to pages. Deactivating a workflow does not remove it from existing pages.', verbose_name='active')),
            ],
            options={
                'verbose_name': 'workflow',
                'verbose_name_plural': 'workflows',
            },
        ),
        migrations.AlterField(
            model_name='site',
            name='site_name',
            field=models.CharField(blank=True, default='Default', help_text='Human-readable name for the site.', max_length=255, verbose_name='site name'),
            preserve_default=False,
        ),
        migrations.CreateModel(
            name='GroupApprovalTask',
            fields=[
                ('task_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Task')),
            ],
            options={
                'verbose_name': 'Group approval task',
                'verbose_name_plural': 'Group approval tasks',
            },
            bases=('wagtailcore.task',),
        ),
        migrations.CreateModel(
            name='WorkflowState',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('status', models.CharField(choices=[('in_progress', 'In progress'), ('approved', 'Approved'), ('needs_changes', 'Needs changes'), ('cancelled', 'Cancelled')], default='in_progress', max_length=50, verbose_name='status')),
                ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')),
                ('current_task_state', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wagtailcore.TaskState', verbose_name='current task state')),
                ('page', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workflow_states', to='wagtailcore.Page', verbose_name='page')),
                ('requested_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='requested_workflows', to=settings.AUTH_USER_MODEL, verbose_name='requested by')),
                ('workflow', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workflow_states', to='wagtailcore.Workflow', verbose_name='workflow')),
            ],
            options={
                'verbose_name': 'Workflow state',
                'verbose_name_plural': 'Workflow states',
            },
        ),
        migrations.CreateModel(
            name='WorkflowPage',
            fields=[
                ('page', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='wagtailcore.Page', verbose_name='page')),
                ('workflow', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workflow_pages', to='wagtailcore.Workflow', verbose_name='workflow')),
            ],
            options={
                'verbose_name': 'workflow page',
                'verbose_name_plural': 'workflow pages',
            },
        ),
        migrations.AddField(
            model_name='taskstate',
            name='workflow_state',
            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='task_states', to='wagtailcore.WorkflowState', verbose_name='workflow state'),
        ),
        migrations.CreateModel(
            name='PageLogEntry',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('label', models.TextField()),
                ('action', models.CharField(blank=True, db_index=True, max_length=255)),
                ('data_json', models.TextField(blank=True)),
                ('timestamp', models.DateTimeField(verbose_name='timestamp (UTC)')),
                ('content_changed', models.BooleanField(db_index=True, default=False)),
                ('deleted', models.BooleanField(default=False)),
                ('content_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name=' ', to='contenttypes.ContentType', verbose_name='content type')),
                ('page', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, related_name=' ', to='wagtailcore.Page')),
                ('revision', models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name=' ', to='wagtailcore.PageRevision')),
                ('user', models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name=' ', to=settings.AUTH_USER_MODEL)),
            ],
            options={
                'verbose_name': 'page log entry',
                'verbose_name_plural': 'page log entries',
                'ordering': ['-timestamp', '-id'],
            },
        ),
        migrations.CreateModel(
            name='WorkflowTask',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
                ('task', models.ForeignKey(limit_choices_to={'active': True}, on_delete=django.db.models.deletion.CASCADE, related_name='workflow_tasks', to='wagtailcore.Task', verbose_name='task')),
                ('workflow', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='workflow_tasks', to='wagtailcore.Workflow', verbose_name='workflow_tasks')),
            ],
            options={
                'verbose_name': 'workflow task order',
                'verbose_name_plural': 'workflow task orders',
                'ordering': ['sort_order'],
                'abstract': False,
                'unique_together': {('workflow', 'task')},
            },
        ),
        migrations.AddConstraint(
            model_name='workflowstate',
            constraint=models.UniqueConstraint(condition=models.Q(('status', 'in_progress'), ('status', 'needs_changes'), _connector='OR'), fields=('page',), name='unique_in_progress_workflow'),
        ),
        migrations.AddField(
            model_name='groupapprovaltask',
            name='groups',
            field=models.ManyToManyField(help_text='Pages at this step in a workflow will be moderated or approved by these groups of users', to='auth.Group', verbose_name='groups'),
        ),
    ]
 

Вывод showmigrations выглядит следующим образом: запуск на Wagtail 2.10.2, попытка запуска на 2.11.8 приводит к той же ошибке, что и раньше:

 admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
home
 [X] 0001_initial
 [X] 0002_contentpage
 [X] 0003_auto_20170427_1205
 [X] 0004_auto_20170427_1210
 [X] 0005_auto_20170427_1214
 [X] 0006_auto_20170427_1215
 [X] 0007_auto_20170427_1216
 [X] 0008_auto_20170430_0530
 [X] 0009_auto_20170430_0551
 [X] 0010_auto_20170430_0639
 [X] 0011_auto_20170430_0642
 [X] 0012_auto_20170501_1035
 [X] 0013_auto_20170501_1046
 [X] 0014_auto_20170501_1055
 [X] 0015_auto_20170501_1101
 [X] 0016_auto_20170501_1103
 [X] 0017_auto_20170501_1106
 [X] 0018_auto_20170501_2305
 [X] 0019_auto_20170501_2325
 [X] 0020_auto_20170501_2350
 [X] 0021_auto_20170501_2354
 [X] 0022_auto_20170502_0000
 [X] 0023_auto_20170502_0012
 [X] 0024_auto_20170502_0030
 [X] 0025_auto_20170502_0054
 [X] 0026_auto_20170502_0237
 [X] 0027_auto_20170502_0524
 [X] 0028_auto_20170502_0853
 [X] 0029_auto_20170502_0856
 [X] 0030_auto_20170511_0012
 [X] 0031_auto_20170511_0017
 [X] 0032_auto_20170511_0021
 [X] 0033_auto_20170511_0023
 [X] 0034_auto_20170511_0025
 [X] 0035_auto_20170511_0027
 [X] 0036_auto_20170511_0030
 [X] 0037_auto_20170511_0032
 [X] 0038_auto_20170511_0034
 [X] 0039_auto_20170511_0035
 [X] 0040_auto_20170511_0037
 [X] 0041_auto_20170511_0039
 [X] 0042_auto_20170511_0045
 [X] 0043_auto_20170511_0048
 [X] 0044_auto_20170511_0054
 [X] 0045_auto_20170511_0056
 [X] 0046_auto_20170511_0105
 [X] 0047_auto_20170511_0106
 [X] 0048_auto_20170511_0111
 [X] 0049_auto_20170511_0113
 [X] 0050_auto_20170511_0114
 [X] 0051_auto_20170513_0708
 [X] 0052_auto_20170513_0709
 [X] 0053_auto_20170515_2351
 [X] 0054_auto_20170516_0021
 [X] 0055_auto_20170516_0344
 [X] 0056_contactpage
 [X] 0057_auto_20170719_1137
 [X] 0058_auto_20170824_0004
 [X] 0059_auto_20170824_0014
 [X] 0060_auto_20171016_0146
 [X] 0061_auto_20171120_0657
 [X] 0062_auto_20171120_0709
 [X] 0063_auto_20171120_0711
 [X] 0064_auto_20171120_0719
 [X] 0065_auto_20171120_0720
 [X] 0066_auto_20171120_0725
 [X] 0067_auto_20171126_0205
 [X] 0068_auto_20171127_2239
 [X] 0069_auto_20171207_0317
 [X] 0070_auto_20180122_0204
 [X] 0071_auto_20180204_2258
 [X] 0072_auto_20180204_2306
 [X] 0073_donatepage
 [X] 0074_contact2page
 [X] 0075_auto_20180705_0128
 [X] 0076_auto_20190926_1406
 [X] 0077_auto_20190926_1557
 [X] 0078_auto_20191001_0448
 [X] 0079_auto_20191003_1227
 [X] 0080_auto_20200211_1115
 [X] 0081_auto_20210217_1427
 [X] 0082_contentholdercategory_contentholderdetailpage_contentholderlistingpage
 [X] 0083_contentholderdetailpage_show_categories
 [X] 0084_auto_20210310_0455
 [X] 0085_contentholderlistingpage_body2
 [X] 0086_flexiblecontactpage
 [X] 0087_auto_20210501_0155
 [X] 0088_auto_20210503_1053
 [X] 0089_auto_20210503_1123
 [X] 0090_auto_20210511_1644
 [X] 0091_auto_20210511_1656
 [X] 0092_auto_20210519_1637
 [X] 0093_auto_20210525_0709
 [X] 0094_footersettings
 [X] 0095_auto_20210607_1158
 [X] 0096_auto_20210623_0242
leads
 [X] 0001_initial
 [X] 0002_auto_20170524_0535
 [X] 0003_auto_20170525_0041
 [X] 0004_auto_20170525_0131
 [X] 0005_auto_20170525_0142
 [X] 0006_auto_20170525_0326
 [X] 0007_leaddb_referer
 [X] 0008_auto_20170525_0851
 [X] 0009_auto_20170526_0230
 [X] 0010_auto_20170526_0232
 [X] 0011_auto_20170526_0313
 [X] 0012_auto_20170526_0321
 [X] 0013_auto_20170526_0324
 [X] 0014_auto_20180322_0049
 [X] 0015_auto_20180713_0351
 [X] 0016_auto_20180713_0357
 [X] 0017_auto_20180713_0708
 [X] 0018_auto_20180713_0715
 [X] 0019_auto_20180713_0754
 [X] 0020_auto_20180713_0803
 [X] 0021_auto_20180713_0804
 [X] 0022_leaddb_other
 [X] 0023_auto_20180720_0341
 [X] 0024_auto_20180724_0224
 [X] 0025_auto_20190717_1540
 [X] 0026_auto_20190717_1616
 [X] 0027_auto_20190717_1618
 [X] 0028_auto_20190718_1533
 [X] 0029_auto_20190721_1146
 [X] 0030_auto_20190924_1501
 [X] 0031_auto_20210217_1427
 [X] 0032_flexibleleaddb
 [X] 0033_auto_20210519_1637
 [X] 0034_auto_20210621_1407
 [X] 0035_auto_20210621_1534
postgres_search
 [X] 0001_initial
 [X] 0002_add_autocomplete
 [X] 0003_title
puput
 [X] 0001_initial
 [X] 0002_blogpage_short_feed_description
 [X] 0003_remove_blogpage_short_feed_description
 [X] 0004_blogpage_short_feed_description
 [X] 0005_auto_20210620_1525
sessions
 [X] 0001_initial
sites
 [X] 0001_initial
 [X] 0002_alter_domain_unique
taggit
 [X] 0001_initial
 [X] 0002_auto_20150616_2121
 [X] 0003_taggeditem_add_unique_index
wagtailadmin
 [X] 0001_create_admin_access_permissions
wagtailcore
 [X] 0001_squashed_0016_change_page_url_path_to_text_field (16 squashed migrations)
 [X] 0017_change_edit_page_permission_description
 [X] 0018_pagerevision_submitted_for_moderation_index
 [X] 0019_verbose_names_cleanup
 [X] 0020_add_index_on_page_first_published_at
 [X] 0021_capitalizeverbose
 [X] 0022_add_site_name
 [X] 0023_alter_page_revision_on_delete_behaviour
 [X] 0024_collection
 [X] 0025_collection_initial_data
 [X] 0026_group_collection_permission
 [X] 0027_fix_collection_path_collation
 [X] 0024_alter_page_content_type_on_delete_behaviour
 [X] 0028_merge
 [X] 0029_unicode_slugfield_dj19
 [X] 0030_index_on_pagerevision_created_at
 [X] 0031_add_page_view_restriction_types
 [X] 0032_add_bulk_delete_page_permission
 [X] 0033_auto_20170401_0651
 [X] 0034_auto_20170510_0533
 [X] 0035_auto_20170822_1810
 [X] 0036_auto_20210624_0046
 [X] 0037_auto_20210624_0316
 [X] 0038_auto_20210624_0634
wagtaildocs
 [X] 0001_initial
 [X] 0002_initial_data
 [X] 0003_add_verbose_names
 [X] 0004_capitalizeverbose
 [X] 0005_document_collection
 [X] 0006_copy_document_permissions_to_collections
 [X] 0005_alter_uploaded_by_user_on_delete_action
 [X] 0007_merge
 [X] 0008_document_file_size
 [X] 0009_document_verbose_name_plural
 [X] 0010_document_file_hash
wagtailembeds
 [X] 0001_initial
 [X] 0002_add_verbose_names
 [X] 0003_capitalizeverbose
 [X] 0004_embed_verbose_name_plural
 [X] 0005_specify_thumbnail_url_max_length
wagtailforms
 [X] 0001_initial
 [X] 0002_add_verbose_names
 [X] 0003_capitalizeverbose
 [X] 0004_add_verbose_name_plural
wagtailimages
 [X] 0001_squashed_0021 (21 squashed migrations)
 [X] 0022_uploadedimage
wagtailmenus
 [X] 0001_initial
 [X] 0002_auto_20160129_0901
 [X] 0003_auto_20160129_2339
 [X] 0004_auto_20160130_0024
 [X] 0005_auto_20160130_2209
 [X] 0006_auto_20160131_1347
 [X] 0007_auto_20160131_2000
 [X] 0008_auto_20160131_2327
 [X] 0009_auto_20160201_0859
 [X] 0010_auto_20160201_1558
 [X] 0011_auto_20160415_1519
 [X] 0012_auto_20160419_0039
 [X] 0013_auto_20160423_1124
 [X] 0014_auto_20160423_1339
 [X] 0015_auto_20160423_1348
 [X] 0016_auto_20160930_0645
 [X] 0017_auto_20161013_1658
 [X] 0018_auto_20161204_2043
 [X] 0019_auto_20161204_2143
 [X] 0020_auto_20161210_0004
 [X] 0021_auto_20170106_2352
 [X] 0022_auto_20170913_2125
 [X] 0023_remove_use_specific
wagtailmetadata
 [X] 0001_initial
 [X] 0002_auto_20160607_2150
 [X] 0003_auto_20160909_1000
 [X] 0004_remove_sitemetadatapreferences
 [X] 0005_metadatasettings
 [X] 0006_drop_metadatasettings
wagtailredirects
 [X] 0001_initial
 [X] 0002_add_verbose_names
 [X] 0003_make_site_field_editable
 [X] 0004_set_unique_on_path_and_site
 [X] 0005_capitalizeverbose
 [X] 0006_redirect_increase_max_length
wagtailsearch
 [X] 0001_initial
 [X] 0002_add_verbose_names
 [X] 0003_remove_editors_pick
 [X] 0004_querydailyhits_verbose_name_plural
wagtailusers
 [X] 0001_initial
 [X] 0002_add_verbose_name_on_userprofile
 [X] 0003_add_verbose_names
 [X] 0004_capitalizeverbose
 [X] 0005_make_related_name_wagtail_specific
 [X] 0006_userprofile_prefered_language
 [X] 0007_userprofile_current_time_zone
 [X] 0008_userprofile_avatar
 [X] 0009_userprofile_verbose_name_plural
 

Увидев, что в последней версии wagtail нет строки «базы», я обнаружил, что если я закомментирую строку «базы» в wagtailcore_migrations, добавленной в мой проект, ошибка исчезнет.

Но потом меня спрашивают:

 You are trying to add a non-nullable field 'locale' to page without a defau< we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py
 

Когда я выбираю 1, я получаю:

 Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
 

Я попытался ввести «en-us» и часовой пояс.сейчас. Но я всегда получаю ошибку при запуске migrate:

 TypeError: Field 'id' expected a number but got...
 

Затем следует либо

  • «эн-нас», когда я вхожу в «эн-нас»
  • дата-время.дата-время, когда я войду в часовой пояс.сейчас

Что мне сюда положить?

Я думаю, что это не создание таблиц базы данных локали.

Я заметил, что он создает файлы в home/wagtailcore_migrations, которые в основном копируют файлы в пакетах сайтов/wagtail/core/миграции. Как это может произойти?

Комментарии:

1. Можете ли вы поделиться полным 0038_auto_20210624_0634.py (или, по крайней мере, достаточным контекстом, чтобы увидеть, в каком классе/модели bases определена опция)?

2. Добавлена полная 0038_auto_20210624_0634.py как и просили.

3. Ах, это миграция, создаваемая внутри wagtailcore? Этого не должно произойти — у wagtailcore никогда не должно быть миграций, кроме тех, которые включены в сам пакет Wagtail, иначе вы столкнетесь с проблемами согласованности с историей миграции. Я подозреваю, что это ошибка Пупута…

4. Да, автоматически генерируется изнутри ядра трясогузки. Я проверил, это идет из дистрибутива трясогузки в /wagtail/core/migrations/0047_add_workflow_models.py.

5. Я не уверен, как вы получили автоматически сгенерированную миграцию, которая дублирует те же создания таблиц, что и собственные миграции Трясогузки , если только вы ранее не взломали эту папку миграции для разрешения более ранних конфликтов миграции-в этом случае проблемы могут вернуться намного дальше, и это может стать очень сложным для распутывания. Не могли бы вы поделиться результатами работы ./manage.py showmigrations ?

Ответ №1:

Основная причина этой проблемы восходит к 2017 году, когда ваш проект был на Wagtail 1.9, и что — то в вашем проекте — скорее всего, эта ошибка Puput- вызвало ложную 0033_auto_20170401_0651 миграцию внутри wagtailcore.

По какой-то причине наличие этой миграции помешало Django увидеть последующие миграции внутри wagtailcore, которые были предоставлены в более поздних версиях Wagtail. (Это не то, чего я ожидал бы: я ожидал бы, что он заметит наличие нескольких миграций 0033 , у которых нет общей истории, и завершится конфликтом миграции.) Вместо этого запуск ./manage.py makemigrations вызвал автоматическую генерацию дополнительных миграций, повторив изменения схемы, которые обычно обрабатывались бы предоставленными миграциями Трясогузки. Это плохо по нескольким причинам:

  • Собственные миграции трясогузки включают некоторые миграции данных, которые автоматически сгенерированные не будут реплицироваться. (Например, Wagtail 1.12 ввел поле «черновик заголовка» и заполнил его из основного поля заголовка; поскольку этот последний шаг был пропущен в вашей версии, вы, скорее всего, получите страницы с пустыми заголовками, появляющимися в администраторе.)
  • Если вы когда-либо установите свой проект в новой среде и выполните новую установку пакета Wagtail на этом этапе, ваша существующая кодовая база и база данных будут содержать ссылки на автоматически созданные миграции, которые не существуют в этой среде, что приведет к ошибкам согласованности ./manage.py migrate .

Поскольку это глубоко укоренившаяся проблема, возникшая много лет назад, которая, возможно, оказала негативное влияние на ваш проект, которое здесь не очевидно, я не могу обещать 100% надежных шагов для ее решения, но следующее должно помочь вам на правильном пути. Я бы рекомендовал сделать резервную копию вашей базы данных и сохранить копию автоматически созданных миграций wagtailcore (где-нибудь за пределами вашей кодовой базы, где они не будут мешать), и, если возможно, начните эти шаги с версии вашей кодовой базы/базы данных, работающей под управлением Wagtail 1.13, до того, как вы начали текущее обновление. (Как упоминалось выше, проблема началась еще до этого момента, но таким образом ваши миграции не зайдут так далеко по «неправильному пути».)

  • Найдите в кодовой базе вашего проекта любые миграции в ваших собственных приложениях, которые относятся к автоматически созданным миграциям 0033_auto_20170401_0651 , 0034_auto_20170510_0533 , 0035_auto_20170822_1810 , 0036_auto_20210624_0046 , 0037_auto_20210624_0316 , 0038_auto_20210624_0634 — например:
     dependencies = [
        ('home', '0123_some_other_migration'),
        ('wagtailcore', '0034_auto_20170510_0533'),  # <- change this line
    ]
     

    Измените их на '0032_add_bulk_delete_page_permission' — таким образом, вы указываете, что эти миграции должны выполняться после последней «реальной» миграции из Wagtail 1.9, но не зависят от автоматически созданных, что позволяет откатить автоматически созданную миграцию без возврата ваших собственных миграций проекта и потенциальной потери данных.

  • Запуск ./manage.py migrate wagtailcore 0032 — мы надеемся, что это должно показать откат автоматически созданных миграций трясогузки, и ничего больше.
  • Удалите пакет Wagtail с pip uninstall wagtail помощью , а затем переустановите ту же версию, которая у вас была — это должно удалить автоматически созданные миграции. pip Внимательно проверьте выходные данные — это может закончиться сообщением о том, что автоматически созданные файлы миграции будут оставлены, и если это так, закройте, удалите эти файлы вручную и повторите команду удаления.
  • Запуск ./manage.py migrate — надеюсь, теперь это должно применяться к реальным миграциям из wagtailcore, а не к автогенерированным.
  • Выполните последовательность обновления Wagtail, как и раньше, обновляя по одной версии за раз и запуская ./manage.py makemigrations и ./manage.py migrate после каждой версии. Если все работает правильно, makemigrations ни в коем случае не следует создавать какие-либо миграции в wagtailcore (или в любом другом собственном приложении Wagtail).