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

Python Django模型,其中只有一行可以具有active=True,python,django,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(Sin

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

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)

首先将
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


首先将
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


只需为主题创建一个模型,并在用户(或某些设置模型)中放置一个代表活动主题的FK。试图在主题模型本身中实施这一点是糟糕的设计。tzaman说实话:),由于您的实现仅适用于1个用户,tzaman解决方案是可伸缩的。我花了一秒钟的时间剖析FK意味着ForeignKey。tzaman说的是实话,我没有注意到这一点。只要有一个主题模型,并在用户(或一些设置模型)中放置一个FK,代表活动主题。试图在主题模型本身中实施这一点是糟糕的设计。tzaman说实话:),由于您的实现仅适用于1个用户,tzaman解决方案是可伸缩的。我花了一秒钟的时间剖析FK意味着ForeignKey。扎曼说的是实话,我是瞎了眼才错过的。