我试图添加slug,使文章的标题出现在url中,但我在控制台上得到这样的消息:
You are trying to add a non-nullable field 'slug' to post without a default; we can't do that Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
self.slug = self.slug or slugify(self.title)
super().save(*args, **kwargs)
4条答案
按热度按时间uttx8gqw1#
Django不能在不允许
null
值的情况下自己添加新字段,特别是当你在这个字段上设置了unique=True
时。要解决这个问题,你必须分步骤执行:1.添加一个包含
null=True
或不包含unique=True
且具有某个默认值的列1.确保数据库中的所有记录都具有唯一值。
1.将字段更改为最终状态。
您可以通过3次迁移完成所有这些操作。下面是执行这些操作的详细步骤。在继续之前,请确保删除以前尝试解决该问题时创建的所有迁移。您可能必须从能够成功应用迁移的环境中撤消这些迁移。
1.添加一列
null=True
或不带unique=True
,并添加一些默认值你可以让Django为你创建这个迁移。简单地编辑你的字段如下:
然后运行
./manage.py makemigrations
。2.确保数据库中所有记录的值都是唯一的。
这一步在某种程度上需要手工完成。首先要求Django通过调用
./manage.py makemigrations YOUR_APP_NAME --empty
为您创建新的、空的迁移。现在打开这个新的迁移文件,并在Migration
类之前添加以下代码(根据您的需要进行调整,特别是确保为每个记录生成唯一的值):现在,添加一个操作,它将在执行此迁移时运行上面定义的代码。为此,将此条目添加到您的迁移的
Migration
类中的operations
列表中:(2nd
RunPython
的参数是一个特殊的函数,它什么也不做,当你想取消应用这个迁移时,它会被执行)。3.将字段更改为最终状态。
这也可以由Django自己处理。将字段更改为最终状态(如您的问题中所示)并再次运行
./manage.py makemigrations
。一切就绪。运行
./manage.py migrate
现在应该成功。注意:可以在单个迁移文件中运行所有3个操作,但应避免。在一个迁移中同时运行数据和模式更改可能会在某些数据库后端上导致问题,因此应完全避免。
u7up0aaq2#
这意味着你尝试在数据库中添加一个新列,但你在表
Post
中存在另一个旧数据。所以旧数据对列slug
没有值。在这种情况下,您需要:
null=True
、slug = models.SlugField(unique=True, null=True)
。py manage.py makemigrations
和py manage.py migrate
。slug
的数据。null=True
、slug = models.SlugField(unique=True)
nx7onnlm3#
试着转一转,转到models.py并将“default”设置为空字符串:
在shell上运行makemigrations。返回models.py并删除默认设置。再次运行makemigrations。这应该已经修复了它。
chy5wohz4#
如果您不关心现有的数据,也不关心迁移历史,最简单的解决方案是将其全部删除并重新开始。
1.删除数据库
1.删除迁移
1.运行
./manage.py makemigrations
1.运行
./manage.py migrate