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

时间:2018-06-19 14:26:06

标签: python django database django-models django-2.0

我有一个模特:

class Model(models.Model):
    price = models.DecimalField(...)

生产数据库中已经有Model个对象。 现在,我将price_total字段添加到该模型中,不能是null

class Model(models.Model):
    price = models.DecimalField(...)
    price_total = models.DecimalField(...)

我希望此price_total等于迁移后的price

类似的东西:

price_total = models.DecimalField(default=this_object.price,...)

是否有可能做到这一点?

我唯一了解的是:

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

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

有更好的方法吗?

2 个答案:

答案 0 :(得分:7)

您可以通过手动编辑迁移来做到这一点,

  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,
        ),
    ]

答案 1 :(得分:3)

您正按计划正确进行。

只需确保在datamigration中完成了第3步(肯定不是通过Django shell)。

这样,您就不会忘记在生产环境中运行它。

我很确定您不能同时添加列和将值设置为与另一列相同。

为了说服自己,您可以搜索https://stackoverflow.com/a/13250005/1435156之类的普通SQL实现