【问题标题】:Django -- new field: How to set default callable for existing objectsDjango -- 新字段:如何为现有对象设置默认可调用对象
【发布时间】:2023-03-03 02:25:01
【问题描述】:

我有一个模型:

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 + 迁移

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

有没有更好的办法?

【问题讨论】:

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


    【解决方案1】:

    你正在正确地做这件事。

    只需确保在 datamigration 中完成第 3 步(当然不是通过 django shell)。

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

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

    为了说服自己,你可以搜索 vanilla SQL 实现,如https://stackoverflow.com/a/13250005/1435156

    【讨论】:

    • 我认为主要问题在于this_object 部分。
    【解决方案2】:

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

    1. 使用 null 进行迁移
    2. 做不为空的迁移
    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,
            ),
        ]
    

    【讨论】:

      猜你喜欢
      • 2014-01-16
      • 2016-01-19
      • 2021-07-26
      • 1970-01-01
      • 2020-06-06
      • 2013-12-26
      • 1970-01-01
      • 2015-05-25
      • 2010-10-20
      相关资源
      最近更新 更多