Django:你正在尝试添加一个不可空的字段'slug'来发布没有默认值的文章;我们不能那么做

9wbgstp7  于 2023-04-22  发布在  Go
关注(0)|答案(4)|浏览(146)

我试图添加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)
uttx8gqw

uttx8gqw1#

Django不能在不允许null值的情况下自己添加新字段,特别是当你在这个字段上设置了unique=True时。要解决这个问题,你必须分步骤执行:
1.添加一个包含null=True或不包含unique=True且具有某个默认值的列
1.确保数据库中的所有记录都具有唯一值。
1.将字段更改为最终状态。
您可以通过3次迁移完成所有这些操作。下面是执行这些操作的详细步骤。在继续之前,请确保删除以前尝试解决该问题时创建的所有迁移。您可能必须从能够成功应用迁移的环境中撤消这些迁移。

1.添加一列null=True或不带unique=True,并添加一些默认值

你可以让Django为你创建这个迁移。简单地编辑你的字段如下:

slug = models.SlugField(unique=True, null=True)

然后运行./manage.py makemigrations

2.确保数据库中所有记录的值都是唯一的。

这一步在某种程度上需要手工完成。首先要求Django通过调用./manage.py makemigrations YOUR_APP_NAME --empty为您创建新的、空的迁移。现在打开这个新的迁移文件,并在Migration类之前添加以下代码(根据您的需要进行调整,特别是确保为每个记录生成唯一的值):

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()

现在,添加一个操作,它将在执行此迁移时运行上面定义的代码。为此,将此条目添加到您的迁移的Migration类中的operations列表中:

migrations.RunPython(populate_posts_slug_field, migrations.RunPython.noop),

(2nd RunPython的参数是一个特殊的函数,它什么也不做,当你想取消应用这个迁移时,它会被执行)。

3.将字段更改为最终状态。

这也可以由Django自己处理。将字段更改为最终状态(如您的问题中所示)并再次运行./manage.py makemigrations
一切就绪。运行./manage.py migrate现在应该成功。
注意:可以在单个迁移文件中运行所有3个操作,但应避免。在一个迁移中同时运行数据和模式更改可能会在某些数据库后端上导致问题,因此应完全避免。

u7up0aaq

u7up0aaq2#

这意味着你尝试在数据库中添加一个新列,但你在表Post中存在另一个旧数据。所以旧数据对列slug没有值。
在这种情况下,您需要:

  • 添加null=Trueslug = models.SlugField(unique=True, null=True)
  • 迁移数据库py manage.py makemigrationspy manage.py migrate
  • 为现有行填充slug的数据。
  • 删除null=Trueslug = models.SlugField(unique=True)
  • 再次迁移。
nx7onnlm

nx7onnlm3#

试着转一转,转到models.py并将“default”设置为空字符串:

author = models.ForeignKey(User, on_delete=models.CASCADE, default="")

在shell上运行makemigrations。返回models.py并删除默认设置。再次运行makemigrations。这应该已经修复了它。

chy5wohz

chy5wohz4#

如果您不关心现有的数据,也不关心迁移历史,最简单的解决方案是将其全部删除并重新开始。
1.删除数据库
1.删除迁移
1.运行./manage.py makemigrations
1.运行./manage.py migrate

相关问题