Django迁移添加默认具有模型功能的字段 [英] Django Migrations Add Field with Default as Function of Model

查看:55
本文介绍了Django迁移添加默认具有模型功能的字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Django模型中添加了一个新的,不可为空的字段,并尝试使用迁移来部署该更改。

I added a new, non-nullable field to my Django model and am trying to use migrations to deploy that change. How would I set default value to use for existing models to be some function of those models rather than a constant?

作为示例,假设我以前有一个 created_on 字段,我刚刚添加了 updated_on 字段,其值最初要设置为模型的 created_on 。我将如何在迁移中做到这一点?

As an example let's say I previously had a created_on field and I just added an updated_on field whose value I want to set initially to the model's created_on. How would I do this in a migration?

这就是我要开始的工作:

This is what I am trying to start with:

    migrations.AddField(
        model_name='series',
        name='updated_as',
        field=models.DateTimeField(default=????, auto_now=True),
        preserve_default=False,
    ),


推荐答案

我刚刚学习了一次迁移的方法!

I just learnt how to do this with a single migration!

运行 makemigrations 时django应该要求您设置一个默认值。在这里定义任何可以让它开心的东西,最后都会得到您提到的迁移 AddField

when running makemigrations django should ask you to set a one-off default. Define whatever you can here to keep it happy, and you'll end up with the migration AddField you mentioned.

migrations.AddField(
    model_name='series',
    name='updated_as',
    field=models.DateTimeField(default=????, auto_now=True),
),

将此操作更改为3个操作:

Change this one operation into 3 operations:


  1. 最初使该字段可为空,因此将添加该列。

  2. 调用一个函数来填充

  3. 更改字段(使用 AlterField )以使其不为空(如上,没有默认值)

  1. initially make the field nullable, so the column will be added.
  2. call a function to populate the field as needed.
  3. alter the field (with AlterField) to make it not nullable (like the above, with no default).

所以您最终得到类似的东西。

so you end up with something like.

migrations.AddField(
    model_name='series',
    name='updated_as',
    field=models.DateTimeField(null=True, auto_now=True),
),
migrations.RunPython(set_my_defaults, reverse_func),
migrations.AlterField(
    model_name='series',
    name='updated_as',
    field=models.DateTimeField(auto_now=True),
),

,您的函数定义如下:

def set_my_defaults(apps, schema_editor):
    Series = apps.get_model('myapp', 'Series')
    for series in Series.objects.all().iterator():
        series.updated_as = datetime.now() + timedelta(days=series.some_other_field)
        series.save()

def reverse_func(apps, schema_editor):
    pass  # code for reverting migration, if any

除非您知道这并不可怕;考虑使用 F表达式和/或数据库函数,以提高大型数据库的迁移性能。

Except, you know, not terrible; consider using F expressions and/or database functions to increase migration performance for large databases.

这篇关于Django迁移添加默认具有模型功能的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆