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!
In Django 2.2 (currently released as beta1) you will be able to use UniqueConstraint which in addition to the list of fields
can be passed a condition
A Q object that specifies the condition you want the constraint to enforce.
For example, UniqueConstraint(fields=['user'], condition=Q(status='DRAFT') ensures that each user only has one draft.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With