Here is the problem:
I have a model like this:
class UserBook(models.Model):
user = models.ForeignKey(User)
book = models.ForeignKey(Book)
is_active = models.BooleanField(default=False)
class Meta:
unique_together = ("user", "book")
Obviously, this model already has a unique together constraint for field user and book. And probably there will be some entries like this in the database:
------------------------------
|user_id book_id is_active |
| 1 1 0 |
| 1 2 0 |
| 1 3 1 |
------------------------------
And I have one more constraint to add, which is each user can have at most one entry that the value of is_active field is 1(True).
Currently I solve this problem by changing the model into this:
class UserBook(models.Model):
user = models.ForeignKey(User)
book = models.ForeignKey(Book)
is_active = models.BooleanField(default=False)
key = models.charFeild(max_length=255, unique=True)
class Meta:
unique_together = ("user", "book")
def save(self, *args, **kwargs):
if self.is_active:
self.key = "%s_%s" %(self.user_id, self.is_active)
else:
self.key = "%s_%s_%s" %(self.user_id, self.is_active, self.book_id)
Add a field key, and customize the save method of this model.
But the max_length cannot be greater than 255 in this approach(which is no need to worry in my case, but sometimes the key field may be very long).
So, I would like to know if there is any more elegant approach to solve this kind of problem.
Thanks!
is_active
field can have 3 potential values:None
,True
,False
and as such Django Admin would present the field as a drop down with 'Yes' / 'No' when editing the item as opposed to a tickbox (boolean). Using Anthony's method solved the problem and should be the accepted answer in 2022. – Parabolic