Baltschun Ali
Baltschun Ali

Reputation: 366

django unique object (not unique field)?

how to make a unique object (not unique per field)

e.g:

name : honda

category : car

success

name : honda

category : bike

success

name : honda

category : bike

failed coz all field have same value to another object

if i use unique at the field, the second case will be failed, coz honda (name) already created

my code :

class Category(models.Model):
    name = models.CharField(max_length=127,unique=True)

    def __str__(self):
        return self.name


class Brand(models.Model):
    name = models.CharField(max_length=127,unique=True)
    category = models.ForeignKey(Category,on_delete=models.CASCADE)         

    def __str__(self):
        return self.name

Upvotes: 1

Views: 1486

Answers (3)

AnonymousUser
AnonymousUser

Reputation: 786

If you are using save

class Brand(models.Model):
    name = models.CharField(max_length=127,unique=True)
    category = models.ForeignKey(Category,on_delete=models.CASCADE)         

    def __str__(self):
        return self.name

    # Here is save
    def save(self, force_insert=False, force_update=False):
      # Whatever you need to do
      if not Brand.objects.filter(name__iexact=self.name).exists():
        super(Brand, self).save(force_insert, force_update)

In my case

class Category(models.Model):
name = CICharField(max_length=255, unique=True, error_messages={'unique':"This category has already been registered."})

def __str__(self):
    return self.name

def get_absolute_url(self):
    # return reverse('article-detail', args=(str(self.id)) )
    return reverse('home')

def save(self, force_insert=False, force_update=False):
    self.name = self.name.lower()
    self.name = capitalizeFirtChar(self.name)
    # If the name already exists
    if not Category.objects.filter(name__iexact=self.name).exists():
        super(Category, self).save(force_insert, force_update)

Upvotes: 0

bryan60
bryan60

Reputation: 29355

Django provides a Meta option called unique together which seems to satisfy this use case:

class Brand(models.Model):
    name = models.CharField(max_length=127)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

    class Meta:
        unique_together = [[“name”, “category”]]

Django docs indicate though that this may be deprecated and recommend the more fully featured UniqueConstraint meta option

class Meta:
    constraints = [
        UniqueConstraint(fields=[“name”,”category”], name=“unique_object”)
    ]

Upvotes: 2

Rafael Zottesso
Rafael Zottesso

Reputation: 1594

You should use a Meta class with unique_together attribute: https://docs.djangoproject.com/en/2.2/ref/models/options/#unique-together

class Brand(models.Model):
    name = models.CharField(max_length=127)
    category = models.ForeignKey(Category,on_delete=models.CASCADE)

    class Meta:
        unique_together = ['name', 'category']

    def __str__(self):
        return self.name

Upvotes: 1

Related Questions