Django模型,其中只有一行可以有active = True

时间:2017-06-23 10:14:03

标签: python django

我正在为我正在处理的项目创建主题设置。我希望用户能够创建多个主题(数据库中的行),但一次只能激活一个主题。

class SingleActiveModel(models.Model):

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        # Save active = False to all other rows or alternative
        super(SingleActiveModel, self).save(*args, **kwargs)

class Theme(SingleActiveModel):
    some_setting = models.SomeField()
    active = models.BooleanField(default=False)

1 个答案:

答案 0 :(得分:1)

首先将active字段放在基类中 - 它是使用它的那个字段,因此它不应该依赖于声明它的子类。

然后,如果有必要,它只是更新其他记录active字段值的主人:

class SingleActiveModel(models.Model):
    active = models.BooleanField(default=False)

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        if self.active:
            # select all other active items
            qs = type(self).objects.filter(active=True)
            # except self (if self already exists)
            if self.pk:
                qs = qs.exclude(pk=self.pk)
            # and deactive them
            qs.update(active=False) 

        super(SingleActiveModel, self).save(*args, **kwargs)


class Theme(SingleActiveModel):
    # the active field is inherited
    some_setting = models.SomeField()

并非这不能解决"每个用户一个活动项"的问题,但是解决方案更简单,参见tzaman的评论:

  

只需拥有一个主题模型,并在表示活动主题的用户(或某些设置模型)中放置一个FK