Django - 新字段:如何为现有对象设置默认可调用对象

Mil*_*ano 3 python database django django-models django-2.0

我有一个模特:

class Model(models.Model):
    price = models.DecimalField(...)
Run Code Online (Sandbox Code Playgroud)

Model生产数据库中已有对象.现在我添加price_total字段到这个模型不可能null.

class Model(models.Model):
    price = models.DecimalField(...)
    price_total = models.DecimalField(...)
Run Code Online (Sandbox Code Playgroud)

我想这price_total等于price迁移之后.

就像是:

price_total = models.DecimalField(default=this_object.price,...)
Run Code Online (Sandbox Code Playgroud)

有可能以某种方式做到这一点吗?

我唯一知道的是:

  1. 使price_total可空的
  2. makemigrations + migrate
  3. 设置price_total等于price例如通过django shell
  4. price_total不能为空
  5. makemigration + migrate

但这种方式有多种缺点,你可以忘记在生产中这样做,它有很多步骤等...

有没有更好的办法?

Bea*_*own 8

你可以通过手动编辑迁移来完成,

  1. 用null做makemigrations
  2. 使用非null来makemigrations
  3. 首先编辑迁移,方法是添加带有更新的数据迁移,并从第二个迁移文件中移动操作
  4. 删除第二个迁移文件,

例如:

from django.db import migrations, models
from django.db.models import F

def set_price_total(apps, schema_editor):
    # Change the myapp on your
    Model = apps.get_model('myapp', 'Model')
    Model.objects.update(price_total=F('price'))


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='model',
            name='price_total',
            field=models.DecimalField(
                decimal_places=2, max_digits=10, null=True),
        ),

        migrations.RunPython(set_price_total),

        migrations.AlterField(
            model_name='model',
            name='price_total',
            field=models.DecimalField(
                decimal_places=2, default=1, max_digits=10),
            preserve_default=False,
        ),
    ]
Run Code Online (Sandbox Code Playgroud)