Django中将CharField改为ForeignKey执行迁移时遇TypeError的解决求助
Django中将CharField改为ForeignKey执行迁移时遇TypeError的解决求助
大家好,我最近在Django项目里遇到了个迁移相关的麻烦,想请各位大佬帮忙支招:
最开始我的Order模型里,discount_code字段是个普通的CharField:
class Order(models.Model): # ... 其他字段 discount_code = models.CharField()
后来开发过程中,我们决定把单纯的文本折扣码改成一个独立的DiscountCode模型,用来存储折扣码、折扣百分比、起止日期等更多信息,所以需要把Order里的discount_code改成ForeignKey:
class Order(models.Model): # ... 其他字段 discount_code = models.ForeignKey(to=DiscountCode, on_delete=models.PROTECT, null=True, blank=True)
问题来了,这期间已经生成了几百条订单,其中一些已经填了折扣码。直接跑迁移的话肯定失败,毕竟CharField和ForeignKey的类型完全不兼容。
于是我尝试自定义迁移文件来处理数据迁移,先创建DiscountCode模型,再把现有订单里的折扣码转换成对应的DiscountCode实例,最后修改Order的字段类型。但运行python manage.py migrate时还是报错了:
TypeError: Tried to update field orders.Order.discount_code with a model instance, <DiscountCode: DiscountCode object (85)>. Use a value compatible with CharField.
下面是我写的迁移文件代码:
# Generated by Django 3.2 on 2022-09-20 05:13 from django.db import migrations, models import django.db.models.deletion from datetime import date def create_discount_objects(apps, schema_editor): Order = apps.get_model('orders', 'Order') DiscountCode = apps.get_model('orders', 'DiscountCode') # Get a list of unique discount codes from the existing orders discount_codes = Order.objects.exclude(discount_code=None).order_by('discount_code').values_list('discount_code', flat=True).distinct('discount_code') # Create new Discount objects for each discount code discount_objects = [] for code in discount_codes: if code is not None: discount_objects.append(DiscountCode(code=code, percentage=10.0, start_date=date(2023,4,20), end_date=date(2023,4,20))) DiscountCode.objects.bulk_create(discount_objects) # Update the existing orders to link them to the corresponding Discount objects for order in Order.objects.all(): if order.discount_code is not None: discount = DiscountCode.objects.get(code=order.discount_code) order.discount_code = discount order.save() class Migration(migrations.Migration): dependencies = [ ('orders', '0012_alter_requiredpart_part_quantity'), ] operations = [ migrations.CreateModel( name='DiscountCode', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(max_length=255, unique=True)), ('percentage', models.FloatField()), ('status', models.CharField(choices=[('active', 'Active'), ('expired', 'Expired'), ('inactive', 'Inactive')], default='active', max_length=10)), ('start_date', models.DateField()), ('end_date', models.DateField()), ('notes', models.TextField(blank=True, null=True)), ], ), migrations.RunPython(create_discount_objects), migrations.AlterField( model_name='order', name='discount_code', field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='orders.discountcode'), ), ]
我之前也找过类似的问题,但都没解决,现在实在没办法了,有没有大佬能帮我看看哪里出问题了?
备注:内容来源于stack exchange,提问作者icesoup
相关产品推荐
相关产品推荐

