views:

22

answers:

1

I have a model:

 class MyModel(models.Model):
     a = models.IntegerField()
     b = models.IntegerField()
     c = models.IntegerField()

Now, I need something like unique_together(a,b, max_occurences=3) constraint to be added to the above model (so that there can be up to 3 values of c for each pair of (a,b), and ideally those 3 values of c should be also unique for given (a,b)), but I don't know what to look for (and if something like this even exists in MySQL). Is there anything like that, or I have to do something like this:

 class MyModel(models.Model):
     a = models.IntegerField()
     b = models.IntegerField()

     c1 = models.IntegerField()
     c2 = models.IntegerField()
     c3 = models.IntegerField()

     class Meta:
         unique_together = ('a', 'b')

-- and handle c1..c3 myself?

A: 

You should override the save() method for the model and check your constraint before each save and raise a ValueError if the constraint is violated.

 class MyModel(models.Model):
     a = models.IntegerField()
     b = models.IntegerField()
     c = models.IntegerField()

     def save(self):
         try:
             # Check values in model here
         except:
             raise ValueError("Cannot save more than 3 Cs with an A")
         super(MyModel, self).save(*args, **kwargs)
Adam Nelson
Yes, but this is fragile - hacker might fire e.g. 20 simultaneous requests and boost his statistics above the allowed level. I'd prefer rock solid db-side solution, if there is any.
Tomasz Zielinski
The only thing I could think of would be something done in the database itself then. You should close this question and open a new one in either PostgreSQL or MySQL with the SQL version of this model. You'll have to maintain it separately though and it won't be portable.Regardless, 20 simultaneous requests wouldn't allow a user to get beyond the save() method.
Adam Nelson
Ok, thank you !
Tomasz Zielinski