import django.db.models.deletion from django.db import migrations, models LEGACY_CATEGORY_NAME_MAP = { "general": "通用", } def forwards(apps, schema_editor): Mission = apps.get_model("mission", "Mission") MissionCategory = apps.get_model("mission", "MissionCategory") db_alias = schema_editor.connection.alias category_cache = {} for mission in Mission.objects.using(db_alias).all().only("id", "merchant_id", "category").iterator(): legacy_value = (mission.category or "").strip() or "general" category_name = LEGACY_CATEGORY_NAME_MAP.get(legacy_value, legacy_value) cache_key = (mission.merchant_id, category_name) category = category_cache.get(cache_key) if category is None: category, _ = MissionCategory.objects.using(db_alias).get_or_create( merchant_id=mission.merchant_id, name=category_name, ) category_cache[cache_key] = category Mission.objects.using(db_alias).filter(id=mission.id).update(category_ref_id=category.id) class Migration(migrations.Migration): dependencies = [ ("basic_info", "0025_customer_uniq_customer_merchant_name"), ("mission", "0003_alter_mission_options"), ] operations = [ migrations.CreateModel( name="MissionCategory", fields=[ ("created_at", models.DateTimeField(auto_now_add=True, verbose_name="创建时间")), ("updated_at", models.DateTimeField(auto_now=True, verbose_name="更新时间")), ("id", models.BigAutoField(primary_key=True, serialize=False)), ("name", models.CharField(max_length=50, verbose_name="分类名称")), ( "merchant", models.ForeignKey( on_delete=django.db.models.deletion.PROTECT, related_name="mission_categories", to="basic_info.merchant", verbose_name="所属商户", ), ), ], options={ "verbose_name": "任务分类", "verbose_name_plural": "任务分类", "ordering": ["id"], "constraints": [ models.UniqueConstraint( fields=("merchant", "name"), name="unique_mission_category_name_per_merchant", ), ], }, ), migrations.AddField( model_name="mission", name="category_ref", field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name="+", to="mission.missioncategory", verbose_name="任务类型", ), ), migrations.RunPython(forwards, migrations.RunPython.noop), migrations.RemoveField( model_name="mission", name="category", ), migrations.RenameField( model_name="mission", old_name="category_ref", new_name="category", ), migrations.AlterField( model_name="mission", name="category", field=models.ForeignKey( on_delete=django.db.models.deletion.PROTECT, related_name="missions", to="mission.missioncategory", verbose_name="任务类型", ), ), ]