代码之家  ›  专栏  ›  技术社区  ›  Huy Than

NullBooleanField始终为True

  •  0
  • Huy Than  · 技术社区  · 10 年前

    请抽出宝贵的时间来帮助我。

    我的应用程序的想法是,每个用户都会收到一组相同的30张卡片,然后他必须决定每张卡片是否重要。

    我有以下两门课:

    class Card(models.Model):
        card_number = models.IntegerField(unique=True)
        content = models.TextField(null=False)
    
        def display(self):
            return self.content
    
        def __str__(self):
            return "Card  " + str(self.card_number)
    
    
    class Choice(models.Model):
        user = models.ForeignKey(User)
        card = models.ForeignKey(Card)
        is_important = models.NullBooleanField(default=None)
    
        class Meta:
            unique_together = ('user','card')
    
        def get_choices(user):
            return Choice.objects.filter(pk=user.pk)
    
        def __str__(self):
            return " %s : Card %d : %s" % (self.user.username, self.card.card_number, self.is_important)
    

    在视图中。py,当用户决定卡片是否重要时:

        card_number= request.GET.get('card_number')
        is_important= request.GET.get('is_important')    
        user = request.user
    
        # assume that user=admin, card_number=1 and is_important is False
    
        if card_number != None and is_important != None:
            try:
                card = Card.objects.get(card_number=card_number)
                choice= Choice.objects.create(user=user, card=card, is_important=is_important)
                print(choice)  # return admin: Card 1: False 
                print(Choice.objects.get(card__card_number=card_number))  # return admin: Card 1: True
                print(choice)  # return admin: Card 1: False 
            except IntegrityError:
                print("User had done with this Card")
    

    我不明白为什么:

    print(choice)  # return admin: Card 1: False 
    

    但是

    print(Choice.objects.get(card__card_number=1))  # return admin: Card 1: True
    

    非常感谢。

    2 回复  |  直到 10 年前
        1
  •  3
  •   user2390182    10 年前

    is_important 是从 GET QueryDict 作为(大概)非空字符串。当您将此类字符串作为参数传递给 (Null)BooleanField ,ORM将其转换为 bool ,由于非空字符串的计算结果为 True ,这就是存储在数据库中的内容。

    假设你通过了 'True' , 'False' 或 'None' 作为的get参数 重要(_I) ,您可以这样做:

    is_important = request.GET.get('is_important')  # this is a string
    is_important = {'True': True, 'False': False, 'None': None}[is_important]
    

    我也许应该补充一下 .objects.create() 和返回的实例 .objects.get() 不一定相同,即使 get call检索由 create 呼叫前者仍将具有作为 kwargs (就像绳子一样 “假” )而后者将具有从数据库检索到的属性(因此 BooleanField 现在将被强制转换为 布尔 ):

    choice = Choice.objects.create(user=user, card=card, is_important=is_important)
    # choice.is_important = 'False'
    
    choice = Choice.objects.get(user=user, card=card, is_important=is_important)
    # choice.is_important = True (= bool('False'))
    
        2
  •  1
  •   trantu    10 年前

    除了schwobaseggl的答案(另一种方式),你最好使用Django forms 具有 cleaned_data 以防止这些并发症。

    推荐文章