You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何简单获取模型内同一时间唯一为True的BooleanField

现有代码的小问题

你当前的实现存在变量覆盖问题:初始voted_for是查询得到的Vote实例,后续if分支中你直接将它赋值为布尔值True,大概率不符合你「获取用户投票对应选项」的实际需求。


方案1:三元表达式(最简写法)

由于业务逻辑已经保证两个布尔字段不会同时为True,直接一行即可得到结果:

voted_for = Vote.objects.get(poller_id=poller_id, user=request.user)
# 返回值可根据需求调整,比如返回选项名、id等
user_vote = 1 if voted_for.poller_choice_one_vote else 2 if voted_for.poller_choice_two_vote else None

方案2:封装为模型属性(复用性最高)

直接在Vote模型中封装判断逻辑,后续所有用到该功能的位置都可以直接调用,无需重复写判断:

class Vote(models.Model):
    poller = models.ForeignKey(Poller, on_delete=models.CASCADE, related_name='vote')
    user = models.ForeignKey(Account, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)
    poller_choice_one_vote = models.BooleanField(default=False)
    poller_choice_two_vote = models.BooleanField(default=False)

    def __str__(self):
        return f'Vote by {self.user}'
    
    @property
    def voted_choice(self):
        if self.poller_choice_one_vote:
            # 可根据需求自定义返回内容
            return 1
        elif self.poller_choice_two_vote:
            return 2
        return None

调用时直接使用voted_for.voted_choice即可拿到结果。


可选优化建议

从模型设计层面来看,两个互斥的布尔字段可以合并为一个choices字段,从数据库层面天然避免出现同时为True的异常,也更节省存储空间:

class Vote(models.Model):
    VOTE_CHOICES = (
        (1, '选项1'),
        (2, '选项2')
    )
    poller = models.ForeignKey(Poller, on_delete=models.CASCADE, related_name='vote')
    user = models.ForeignKey(Account, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)
    vote_choice = models.SmallIntegerField(choices=VOTE_CHOICES, null=True, blank=True)

    def __str__(self):
        return f'Vote by {self.user}'

内容的提问来源于stack exchange,提问作者JSRB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 19:24:05