Search code examples
pythondjangoslugify

Slug error in django


I am new to django and currently learning the basics. However, I am stuck with the slug module.

Hope to find a solution. Thanks in advance.

While running the migration command

python manage.py makemigrations rango
python manage.py migrate

I keep getting this error:

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

Models.py file

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 tutorial says "Since we did not provide a default value for the slug, and we already have existing data in the model, then the migrate command will give you two options. Select the option to provide a default, and enter ‘’. Dont worry this will get updated shortly. Now re-run your "populate.py" script. Since the save method is called for each Category, the overrided save method will be executed, updating the slug field. Run the server, and inspect the data in the models via the admin interface." (link of the tutorial is mentioned in point 3 at the bottom)

populate.py file

import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kiran_blog_project.settings')

import django
django.setup()

from exodus.models import Category, Page


def populate():
    python_cat = add_cat('Python',128,64)

    add_page(cat=python_cat,
        title="Official Python Tutorial",
        url="http://docs.python.org/2/tutorial/",views=20)

    add_page(cat=python_cat,
        title="How to Think like a Computer Scientist",
        url="http://www.greenteapress.com/thinkpython/", views=19)

    add_page(cat=python_cat,
        title="Learn Python in 10 Minutes",
        url="http://www.korokithakis.net/tutorials/python/",views=17)

    django_cat = add_cat("Django",64,32)

    add_page(cat=django_cat,
    title="Official Django Tutorial",
    url="https://docs.djangoproject.com/en/1.5/intro/tutorial01/",views=30)

    add_page(cat=django_cat,
        title="Django Rocks",
        url="http://www.djangorocks.com/",views=21)

    add_page(cat=django_cat,
        title="How to Tango with Django",
        url="http://www.tangowithdjango.com/",views=50)

    frame_cat = add_cat("Other Frameworks",32,16)

    add_page(cat=frame_cat,
        title="Bottle",
        url="http://bottlepy.org/docs/dev/",views=13)

    add_page(cat=frame_cat,
        title="Flask",
        url="http://flask.pocoo.org",views=16)

    # Print out what we have added to the user.
    for c in Category.objects.all():
        for p in Page.objects.filter(category=c):
            print "- {0} - {1}".format(str(c), str(p))

def add_page(cat, title, url, views):
    p = Page.objects.get_or_create(category=cat, title=title)[0]
    p.url=url
    p.views=views
    p.save()
    return p

def add_cat(name,views,likes):
    c = Category.objects.get_or_create(name=name)[0]
    c.views=views
    c.likes=likes
    c.save()
    return c

# Start execution here!
if __name__ == '__main__':
    print "Starting  population script..."
    populate()

So my question is,

1.After selecting the option to provide the default value what value should I enter?

2.Also the instruction states that, I need to run "populate.py" file. But before running this file, I think I need to include the slug field. So can someone specify the changes in the "populate.py" field?

3.my django tutorial link

4.Solution to this same query, I even tried out the answer using uuid but did not work out.


Solution

  • You have to alter your migration file to avoid unique constrains. According this instruction, modify your last migration file(which added the slug field to the model) like this:

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

    Migration file: (i.e: 0004_category_slug.py)

    class Migration(migrations.Migration):
    
        dependencies = [
            ('yourproject', '0003_remove_category_slug'),
        ]
    
        def gen_slug(apps, schema_editor):
            for row in Category.objects.all():
                row.slug = slugify(row.name)
                row.save()
    
        operations = [
            migrations.AddField(
                model_name='category',
                name='slug',
                field=models.SlugField(default=uuid.uuid4),
                preserve_default=True,
            ),
            migrations.RunPython(gen_slug),
    
            migrations.AlterField(
                model_name='category',
                name='slug',
                field=models.SlugField(default=uuid.uuid4, unique=True),
            ),
        ]