我有这个模型
class Order(models.Model):
...
discount_code = models.CharField()
但在开发的某个阶段,我们决定从纯文本 discount_codes 转移到具有代码、百分比、开始和结束日期等的模型。这意味着我们必须更新到外键
class Order(models.Model):
...
discount_code = models.ForeignKey(to=DiscountCode, on_delete=models.PROTECT, null=True, blank=True)
这期间产生了几百个订单,自然有些有优惠码。当谈到运行迁移时,我们无法做到,仅仅是因为 char 不是外键。
所以我决定更新迁移以处理从 char 到对象的移动,但它仍然失败。
这是迁移文件
# 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'),
),
]
这是我在运行时得到的错误
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.
任何帮助将不胜感激。
P.S 这没有帮助similar question
建议分步执行此操作(只涉及基础知识......没有复杂的手动迁移修改):
Discount
Order
中定义新的外键,临时名称如下:discount_code_fk = models.ForeignKey(...)
做迁移
循环:像您一样从代码创建所有
Discount
实例并将Discount
实例分配给discount_code_fk
从模型中删除
discount_code
Discount
迁移
在模型中将
discount_code_fk
重命名为discount_code
Discount
迁移