Is there any more elegant way to add a value sensitive unique together constraint in Django Model?
问题是:
我有一个这样的模型:
1 2 3 4 5 6 7 | class UserBook(models.Model): user = models.ForeignKey(User) book = models.ForeignKey(Book) is_active = models.BooleanField(default=False) class Meta: unique_together = ("user","book") |
显然,这个模型已经为现场用户和图书提供了一个独特的together约束。数据库中可能会有这样的条目:
1 2 3 4 5 6 | ------------------------------ |user_id book_id is_active | | 1 1 0 | | 1 2 0 | | 1 3 1 | ------------------------------ |
号
我还有一个要添加的约束,即每个用户最多可以有一个条目,is_active字段的值为1(true)。
目前,我通过将模型改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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) |
添加字段键,并自定义此模型的保存方法。
但在这种方法中,最大长度不能大于255(在我的例子中不需要担心,但有时键字段可能很长)。
所以,我想知道是否有更优雅的方法来解决这类问题。
谢谢!
将
1 2 | # Equals user ID if active; otherwise null. is_active = models.IntegerField(null = True, unique = True) |
号
用户ID在列中是唯一的(满足您所需的约束),并且列中的许多空值不会违反约束,如本文所讨论的。
在Django 2.2(目前发布为beta1)中,您将能够使用唯一约束,除了
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.
号
您只需要在唯一约束中包含
1 2 3 4 5 6 7 | class UserBook(models.Model): user = models.ForeignKey(User) book = models.ForeignKey(Book) is_active = models.BooleanField(default=False) class Meta: unique_together = ("user","book","is_active") |
也就是说,我建议让用户重新激活一本书,而不是让用户拥有一个不活动和活动的版本。
旁注:为了一些额外的好处,从多到多看(你可以把