I'm learning Django from Tango with Django but I keep getting this error when I type:
python manage.py makemigrations rango
python manage.py migrate
This is the output:
django.db.utils.IntegrityError: UNIQUE constraint failed: rango_category__new.slug
Models.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
The reason for this constrain could be that you didn't have any field called slug
in Category
class when you have initially migrated it (First Migration), and after adding this field in the model, when you ran makemigrations
, you have set default value to something static value(i.e None
or ''
etc), and which broke the unique constrain for the Category's table's slug column in which slug should be unique but it isn't because all the entry will get that default value.
To solve this, you can either drop the database and migration files and re-run makemigrations
and migrate
or set a unique default value like this:
slug = models.SlugField(unique=True, default=uuid.uuid1)
According to Migrations that add unique fields, modify your migration file to overcome unique constrain. For example, modify your migration file (which added the slug field to the model) like this:
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),
),
]