Python Django:您正在尝试添加一个不可为空的字段';slug';在没有违约的情况下发布;我们可以';不要那样做
我正在尝试添加slug,以便在url中显示文章标题,但我在控制台上收到以下消息:Python Django:您正在尝试添加一个不可为空的字段';slug';在没有违约的情况下发布;我们可以';不要那样做,python,django,slug,Python,Django,Slug,我正在尝试添加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
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)
Django无法在此处不允许使用
null
值的情况下自行添加新字段,尤其是在此字段上设置了unique=True
时。要解决该问题,必须分步骤执行:
null=True
或不具有unique=True
且具有某些默认值的列null=True
或不具有unique=True
且具有某些默认值的列
您可以让Django为您创建此迁移。只需编辑字段,使其看起来像:
slug = models.SlugField(unique=True, null=True)
然后运行/manage.py makemigrations
2.确保数据库中的所有记录都具有唯一值。
在某种程度上,这一步骤必须手工制作。首先,通过调用/manage.py makemigrations-YOUR\u-APP\u-NAME--empty
,让Django为您创建新的空迁移。现在打开这个新的迁移文件,并在迁移
类之前添加此代码(根据您的需要进行相应调整,尤其要确保为每个记录生成唯一的值):
def populate_posts_slug_field(apps, schema_editor):
for post in apps.get_model('YOUR_APP_NAME.post'):
post.slug = # generate a unique value for every post here
post.save()
现在,添加一个操作,该操作将在执行此迁移时运行上面定义的代码。为此,请将此条目添加到迁移的Migration
类中的operations
列表中:
migrations.RunPython(populate_posts_slug_field, migrations.RunPython.noop),
(RunPython的第二个参数是一个特殊函数,它完全不做任何事情,当您想要取消应用此迁移时,它将被执行)
3.将字段更改为最终状态。
这也可以由Django自己处理。将字段更改为最终状态(如您的问题所示),然后再次运行/manage.py makemigrations
你都准备好了。现在运行/manage.py migrate
应该会成功
注意:可以在单个迁移文件中运行所有3个操作,但应避免。在一次迁移中同时运行数据和架构更改可能会导致某些数据库后端出现问题,因此应该完全避免。这意味着您尝试在数据库中添加一个新列,但在表
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)
- 再次迁移