3

I am going through Tango with Django and I can't solve this excercise. I get django.db.utils.IntegrityError: UNIQUE constraint failed: rango_category.name error. This is after I try to implement views attribute to Category object. This is a excerpt from my database population script. I though maybe that I should makemigrations and then migrate to update models for DB. However, this didn't help.

    cats = {
    'Python' : {'pages': python_pages, 'views':128},
    'Django': {'pages': django_pages, 'views':128},
    "Other Frameworks": {'pages':other_pages, 'views':128},
    }

for cat, cat_data in cats.items():
    c = add_cat(cat, cat_data['views'])
    for p in cat_data["pages"]:
        add_page(c, p['title'], p['url'])

for c in Category.objects.all():
    for p in Page.objects.filter(category=c):
        print("- {0} - {1}".format(str(c), str(p)))

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

Adding Category model:

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



class Meta:
    verbose_name_plural = 'Categories'

def __str__(self):
        return self.name
neptunereach
  • 105
  • 2
  • 7
  • Check this! https://stackoverflow.com/questions/29373887/django-db-utils-integrityerror-unique-constraint-failed-rango-category-new-sl – Cuong Vu Jun 07 '18 at 17:58
  • I think this is because `name` field in `Category` has the argument `unique=True` Show your models `Category` – Lemayzeur Jun 07 '18 at 18:01

2 Answers2

5

You got the error because unique = True in name = models.CharField(max_length=128, unique=True) means that Django will raise constraint errror UNIQUE constraint failed in case you trying to save a new instance with the same name value; A violation of the unique constraint

get_or_create doesn't work because views=views that may be different even though name equals name

When you create or get your instance, you can do so with only the name field

def add_cat(name, views):
    c = Category.objects.get_or_create(name=name, views=views)[0]
    c.views=views
    c.save()
    return c
Lemayzeur
  • 8,297
  • 3
  • 23
  • 50
3

As mentioned in comments, the error is caused by violation of the unique constraint on Category.name. The reason that this is happening might not be completely obvious, however. When you call Category.objects.get_or_create, you are asking django to look for an object with both the given name and the given number of views. If one is not found, then django tries to create one, which violates the unique constraint if there is already a Category of the same name, but with a different number of views. Depending on desired behavior, you can fix by either:

  • remove unique constraint altogether
  • change unique constraint to a unique_together constraint
  • change the model reference to first get or create by name, then set (or modify) the views attribute (don't forget to save)
RishiG
  • 2,790
  • 1
  • 14
  • 27