如何删除 Django 中的默认值函数

How to remove a default value function in Django

this question answer 的评论中,我询问了如何删除具有默认值函数的字段。综上,示例代码为:

def get_deadline():
    return datetime.today() + timedelta(days=20)

class Bill(models.Model):
    name = models.CharField(max_length=50)
    customer = models.ForeignKey(User, related_name='bills')
    date = models.DateField(default=datetime.today)
    deadline = models.DateField(default=get_deadline)

我对代码的问题是:

How do you remove the deadline field again while also deleting the get_deadline function? I have removed a field with a function for a default value, but now Django crashes on startup after removing the function. I could manually edit the migration, which would be ok in this case, but what if you simply changed the default function, and wanted to remove the old function?

我最终删除了引用它的迁移的默认部分,但是你如何很好地删除它?

我能想到的唯一方法是压缩迁移,这样使用该函数的迁移就会消失,但这并不总是一个选项。

How do you remove the deadline field again while also deleting the get_deadline function?

我认为同时删除两者(即“同时”删除另一个)不是正确的做法。相反:

  • 添加迁移以删除该字段。将该迁移部署为修订版 N.

  • 确认没有任何东西再使用该函数。

  • 在修订版 N+M(即以后的修订版)中删除未使用的功能。

这样,数据库将匹配代码的状态,因为迁移是该代码状态的一部分:当您将数据库迁移回修订版 N 的状态时,函数将在那里。当您将数据库迁移到修订版 N+M 的状态时,您将不再需要该功能。

看来您自己已经找到了答案。在删除 get_deadline 函数之前,您必须将其从任何使用它的迁移中删除。有两种方法可以做到这一点:

  1. 编辑使用 get_deadline 的迁移以使用不同的默认值。
  2. 压缩迁移以删除引用 get_deadline 的迁移。

遵循 Historical Models 中的文档:

References to functions in field options such as upload_to and limit_choices_to and model manager declarations with managers having use_in_migrations = True are serialized in migrations, so the functions and classes will need to be kept around for as long as there is a migration referencing them. Any custom model fields will also need to be kept, since these are imported directly by migrations.

.....

To remove old references, you can squash migrations or, if there aren’t many references, copy them into the migration files.

使用方法获取 default 字段选项的值与对 upload_to 字段的描述相同。如果您想删除该方法,文档本身为您提供了两个选项:

  1. 挤压迁移 - 如果您不再需要它们
  2. 编辑迁移文件:将函数复制到迁移文件并在迁移中编辑引用。

评论更新:

编辑迁移文件的第 2 步中,我刚刚包含了文档中描述的方法。您可以选择如何编辑迁移。您可以复制迁移文件中的函数并编辑引用,或者您可以只从迁移文件中删除默认字段,或者您可以使用不同文件中的另一个函数。

我直接的回答是删除 sqlite3.db 并删除每个应用程序的迁移文件夹中除 __init__.py 之外的所有迁移。

然后再做 python

$manage.py makemigrations
$python manage.py migrate