Django 无法自行添加新字段null
此处允许的值,尤其是当您有unique=True
设置在该字段上。要解决该问题,您必须分步骤执行:
- 添加一列
null=True
或没有unique=True
并有一些默认值
- 确保数据库中的所有记录都具有唯一值。
- 将字段更改为最终状态。
所有这些操作都可以通过 3 次迁移来完成。以下是执行此操作的详细步骤。在继续之前,请确保删除之前尝试解决该问题时创建的所有迁移。您可能必须从能够成功应用这些迁移的环境中撤消这些迁移。
1. 添加一列null=True
或没有unique=True
并有一些默认值
您可以让 Django 为您创建此迁移。只需将您的字段编辑为如下所示:
slug = models.SlugField(unique=True, null=True)
And run ./manage.py makemigrations
这样做之后。
2. 确保数据库中的所有记录都有唯一的值。
这一步在某种程度上必须是手工制作的。首先要求 Django 通过调用为您创建新的空迁移./manage.py makemigrations YOUR_APP_NAME --empty
。现在打开这个新的迁移文件并在Migration
class:
def populate_posts_slug_field(apps, schema_editor):
for post in apps.get_model("YOUR_APP_NAME", "post").objects.all():
post.slug = # generate a unique value for every post here
post.save()
现在,添加一个操作,该操作将在执行此迁移时运行上面定义的代码。为此,请将此条目添加到operations
列出在Migration
您的迁移类别:
migrations.RunPython(populate_posts_slug_field, migrations.RunPython.noop),
(第二个参数RunPython
是一个特殊函数,它绝对不执行任何操作,当您想要取消应用此迁移时,它将被执行)。
3. 将字段更改为最终状态。
这也可以由 Django 本身来处理。将您的字段更改为最终状态(如您的问题所示)并运行./manage.py makemigrations
再次。
你已经准备好了。跑步./manage.py migrate
现在应该成功了。
注意:可以在单个迁移文件中运行所有 3 个操作,但应避免这样做。在一次迁移中同时运行数据和架构更改可能会导致某些数据库后端出现问题,因此应该完全避免。