如何在Django中将现有Charge字段更改为外键

n53p2ov0  于 2023-04-22  发布在  Go
关注(0)|答案(1)|浏览(106)

我有一个模型

class Order(models.Model):
 ...
 discount_code = models.CharField()

但在开发过程中的某个时候,我们决定从仅包含文本的discount_codes转移到包含代码、百分比、开始和结束日期等的Model。这意味着我们必须更新到外键

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

csga3l58

csga3l581#

建议分步骤执行此操作(仅涉及基础知识...无需复杂的手动迁移修改):
1.定义型号Discount
1.在模型Order中定义新的ForeignKey,临时名称如下:

discount_code_fk = models.ForeignKey(...)

1.进行迁移

  1. loop:按照您的操作,从代码中创建所有Discount示例,并将Discount示例分配给discount_code_fk
    1.从型号Discount中删除discount_code
    1.迁移
    1.在型号Discount中将discount_code_fk重命名为discount_code
    1.迁移

相关问题