Django:您正在尝试添加一个不可为空的字段“slug”以在没有默认值的情况下进行发布;我们不能那样做

2023-11-22

我正在尝试添加 slug,以便帖子的标题出现在网址中,但我在控制台上收到此消息:

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

模型.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)

Django 无法自行添加新字段null此处允许的值,尤其是当您有unique=True设置在该字段上。要解决该问题,您必须分步骤执行:

  1. 添加一列null=True或没有unique=True并有一些默认值
  2. 确保数据库中的所有记录都具有唯一值。
  3. 将字段更改为最终状态。

所有这些操作都可以通过 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 个操作,但应避免这样做。在一次迁移中同时运行数据和架构更改可能会导致某些数据库后端出现问题,因此应该完全避免。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django:您正在尝试添加一个不可为空的字段“slug”以在没有默认值的情况下进行发布;我们不能那样做 的相关文章

随机推荐