【问题标题】:How to remove a default value function in Django如何在 Django 中删除默认值函数
【发布时间】:2017-04-13 16:18:11
【问题描述】:

在对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)

我对代码的问题是:

如何在删除 deadline 字段的同时再次删除 get_deadline 功能?我已经删除了一个带有函数的字段 默认值,但现在 Django 在删除后在启动时崩溃 功能。我可以手动编辑迁移,这样就可以了 这种情况下,但是如果您只是更改了默认功能,并且 想要移除旧功能?

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

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

【问题讨论】:

    标签: django django-models django-migrations


    【解决方案1】:

    如何在删除get_deadline函数的同时再次删除deadline字段?

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

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

    • 确认没有任何东西正在使用该功能。

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

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

    【讨论】:

    • 这行不通。该函数仍将在早期版本中引用。
    • “修订”是指“迁移”:)
    【解决方案2】:

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

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

    【讨论】:

    • 或根据@AKS 的回答:3. 将函数复制到迁移文件并在迁移中编辑引用
    【解决方案3】:

    遵循Historical Models的文档:

    对字段选项中函数的引用(例如upload_tolimit_choices_to)以及具有use_in_migrations = True 的管理器的模型管理器声明在迁移中被序列化,因此函数和类需要保留很长时间因为有一个迁移引用它们。还需要保留任何自定义模型字段,因为这些字段是通过迁移直接导入的。

    .....

    要删除旧引用,您可以压缩迁移,或者,如果引用不多,将它们复制到迁移文件中

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

    1. Squash 迁移 - 如果您不再需要这些迁移
    2. 编辑迁移文件:将函数复制到迁移文件并编辑迁移中的引用。

    来自 cmets 的更新:

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

    【讨论】:

    • 或根据@Alasdair 的回答:3. 编辑迁移以使用不同(或不)默认值
    • 我想说两个答案都只建议两个步骤 1) 压缩迁移 2) 编辑迁移。如何准确地编辑迁移是您的选择。您可以在那里复制函数并编辑参考。或者,您可以从那里删除默认字段,或者您可以从其他地方使用另一个功能。 :)
    • 我已在答案中添加了我的 cmets。
    • 我希望在更新部分阐明第二步
    • @beruic:已经澄清和解释过了。您实际上不需要在答案中再次添加第 2 步。
    【解决方案4】:

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

    然后再做 python

    $manage.py makemigrations
    $python manage.py migrate
    

    【讨论】:

    • 如果我的实时系统中的数据无法承受在 MySQL 或 PostgreSQL 数据库上丢失,该怎么办?
    • 那么在你的实时数据中编码就是一个坏主意。我猜
    • 好吧,如果无法升级实时数据,则根本不需要迁移。如果你不能升级实时数据,你就不能发展你的软件。
    • 但是依赖迁移文件进行数据库迁移对我来说就像一个笑话。
    • 那就想出一个更好的办法:)
    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 2017-07-11
    • 2016-03-13
    • 1970-01-01
    • 2016-11-16
    • 2020-02-02
    • 1970-01-01
    • 2020-07-21
    相关资源
    最近更新 更多