Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django unique_together doesn't work with ForeignKey=None

I saw some ppl had this problem before me, but on older versions of Django, and I'm running on 1.2.1.

I have a model that looks like:

class Category(models.Model):
 objects = CategoryManager()

 name = models.CharField(max_length=30, blank=False, null=False)
 parent = models.ForeignKey('self', null=True, blank=True, help_text=_('The direct parent category.'))

 class Meta:
  unique_together = ('name', 'parent')

Whenever i try to save in the admin a category with a parent set to None, it still works when there's another category with the SAME name and parent set to None.

Ideas on how to solve this gracefully?

like image 548
ydaniv Avatar asked Aug 15 '10 16:08

ydaniv


1 Answers

The unique together constraint is enforced at the database level, and it appears that your database engine does not apply the constraint for null values.

In Django 1.2, you can define a clean method for your model to provide custom validation. In your case, you need something that checks for other categories with the same name whenever the parent is None.

class Category(models.Model):
    ...
    def clean(self):
        """
        Checks that we do not create multiple categories with 
        no parent and the same name.
        """
        from django.core.exceptions import ValidationError
        if self.parent is None and Category.objects.filter(name=self.name, parent=None).exists():
            raise ValidationError("Another Category with name=%s and no parent already exists" % self.name)

If you are editing categories through the Django admin, the clean method will be called automatically. In your own views, you must call category.fullclean().

like image 128
Alasdair Avatar answered Sep 20 '22 06:09

Alasdair