Django数据库工具包出现完整性错误:rango_category_new.slug的唯一约束失败。

38

我正在使用《Tango with Django》学习Django,但是当我输入以下内容时,我一直遇到这个错误:

python manage.py makemigrations rango
python manage.py migrate

这是输出结果:

django.db.utils.IntegrityError: UNIQUE constraint failed: rango_category__new.slug

模型.py:

from django.db import models
from django.template.defaultfilters import slugify

class Category(models.Model):
    name = models.CharField(max_length=128, unique=True)
    views = models.IntegerField(default=0)
    likes = models.IntegerField(default=0)
    slug = models.SlugField(unique=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Category, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.name


class Page(models.Model):
    category = models.ForeignKey(Category)
    title = models.CharField(max_length=128)
    url = models.URLField()
    views = models.IntegerField(default=0)

    def __unicode__(self):
        return self.title

5
如果一个回答对你有帮助,一般的礼节是将其标记为被采纳的答案。我遇到了同样的问题,@ruddra的回答对我有用。 - user1048839
13个回答

47
这个限制的原因可能是当您最初迁移(第一次迁移)Category类时,您没有任何称为slug的字段,并且在将此字段添加到模型后,运行makemigrations时,您将默认值设置为某些静态值(即None''等),这将破坏了Category表的slug列的唯一约束条件,其中slug应该是唯一的,但实际上它不是,因为所有条目都会获得默认值。

要解决此问题,您可以删除数据库和迁移文件并重新运行makemigrationsmigrate,或者像这样设置唯一的默认值:

slug = models.SlugField(unique=True, default=uuid.uuid1)

编辑:

根据添加唯一字段的迁移,修改您的迁移文件以克服唯一约束。例如,将添加了slug字段的模型的迁移文件修改如下:

import uuid
from app.models import Category  # where app == tango_app_name

class Migration(migrations.Migration):

    dependencies = [
        ('yourproject', '0003_remove_category_slug'),
    ]

    def gen_uuid(apps, schema_editor):
        for row in Category.objects.all():
            row.slug = uuid.uuid4()
            row.save()

    operations = [
        migrations.AddField(
            model_name='category',
            name='slug',
            field=models.SlugField(default=uuid.uuid4),
            preserve_default=True,
        ),
        migrations.RunPython(gen_uuid),

        migrations.AlterField(
            model_name='category',
            name='slug',
            field=models.SlugField(default=uuid.uuid4, unique=True),
        ),
    ]

第一个在管理员页面中给了我错误:u“在'CategoryForm'中找不到' slug '键”。我无法使用uuid.uuid1,因为我不知道在哪里导入它,它会显示'uuid'未定义。 - ArrowsX
1
第一个问题,请查看此链接:https://dev59.com/QU3Sa4cB1Zd3GeqPuFO0。第二个问题,请使用`import uuid。对于第二个解决方案,请不要忘记从应用程序的迁移目录中删除最后一个迁移文件(即005_add_slug.py`),然后重新运行makemigrations/migrate命令。 - ruddra
1
谢谢你的帮助,但以防万一我想补充一下,我必须从文件夹中删除最后一个迁移文件,因为在第一次迁移时我仍然遇到了这个问题,直到我删除了这些文件。 - Manza
1
@ruddra 这太棒了!非常感谢您的答案...它解决了我的问题! - Trilla
我认为应该注意到,有时候丢弃数据库或删除所有内容是“杀鸡焉用牛刀”,您应该检查现有数据是否与新的约束条件相冲突。 - d6bels

20

我有一个带有唯一属性的字段,但它并不唯一[例如2次相同的值]

python3 manage.py migrate --fake
然后。
python3 manage.py makemigrations

python3 manage.py migrate

这个方法起了作用。


3
这意味着一个 slug 应该是唯一的。你可能在模型中有一些数据。你需要删除该模型中的所有数据并且你需要再次迁移。

在这种情况下,你有两种方法来修复错误;

  1. 你需要从 Django 管理界面 中将其删除。往往情况下,在尝试打开模型时可能会出现错误。

  2. 打开命令提示符

move to project -> py manage.py shell -> from yourappname.models import modelname -> modelname.objects.delete()

如果你为你的模型定义了一个产品经理,那么你就需要定义一个删除函数。之后你应该进行makemigrationsmigrate,然后继续第二步。"最初的回答"

1

我曾经遇到同样的问题,尝试了所有建议的答案。最后对我有效的方法是,在模型中将slug字段定义为URL,并运行makemigrations命令。然后在makemigrations生成的文件中,在基本URL的末尾添加一个随机数,例如:

由 Django 3.2.3 在2022年2月2日20:58生成

from django.db import migrations, models from random import randint

class Migration(migrations.Migration):

dependencies = [
    ('blog', '0002_remove_post_slug1'),
]

operations = [
    migrations.AddField(
        model_name='post',
        name='slug',
        field=models.URLField(blank=True, default='http:/salpimientapa.com/' + str(randint(100000,999999))),
    ),
]

执行了 python manage.py migrate 命令后,我将 slug 作为 SlugModel 进行了编辑,并再次执行了 makemigrations 和 migrate 命令。


1
我刚遇到了一个类似的错误:Django唯一约束失败。我试着检查代码很长时间,但是没有解决它。最后我使用SQLiteStudio来检查数据,并发现数据有问题:我无意中添加了两个相同的实例,这违反了唯一约束。坦率地说,我没有想到错误会如此幼稚和简单,因此花了很长时间才发现!

帮我节省了很多时间。这里也是一样,一切都很好,但我在处理迁移时尝试创建独特的东西,但数据库中的某些数据不符合要求。 - d6bels

0

对我有用的是进入管理员界面并更改重复的slug值,然后再次运行迁移。


0
只需删除迁移文件夹中的最后一个迁移文件
然后运行
python manage.py makemigrations 
python manage.py migrate

0

我遇到了同样的问题,并通过在管理员中填充唯一值并且不留空来解决我的slugfied。


0
基本上:您可以在一次操作中添加没有unique=true的字段,进行数据迁移以生成正确的shortuuids,然后再将该字段更改为unique。

0
我也遇到了这个错误, 我在 Django 项目中删除了我的数据库(例如 db.sqlite3), 然后运行了代码。
python manage.py makemigrations

python manage.py migrate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接