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
相关产品推荐
相关产品推荐

