【问题标题】:NullBooleanField is always TrueNullBooleanField 始终为 True
【发布时间】:2016-05-14 19:08:16
【问题描述】:

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

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

我有 2 个类如下:

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)

在views.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

谢谢!

【问题讨论】:

  • 我不确定这是否相关,但您的 Choice 模型定义中的 return 语句需要缩进另一个级别
  • 并在Meta 声明中
  • 你能提供一个你提出的 GET 请求的例子吗?
  • 谢谢大家。我已经尝试了 schwobaseggl 的解决方案,它就像一个魅力。顺便说一句,我的 GET 请求是:“127.0.0.1:8000/list/?card=3&choice=False

标签: python django django-models django-database


【解决方案1】:

is_important 取自 GET QueryDict 作为(可能)非空字符串。当您将这样的字符串作为(Null)BooleanField 的参数传递时,ORM 会将其转换为bool,并且由于非空字符串评估为True,这就是存储在数据库中的内容。

假设您将'True''False''None' 作为is_important 的get 参数传递,您可以这样做:

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 调用检索到由create 调用插入的数据库记录。前者仍将具有作为kwargs 传递的属性(如字符串'False'),而后者将具有从数据库中检索到的属性(因此BooleanField 的值现在将转换为@ 987654339@):

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'))

【讨论】:

  • 感谢您的解决方案。 {'True': True, 'False': False, 'None': None}[is_important] 真是个聪明的方法!
【解决方案2】:

除了 schwobaseggl 的回答(另一种方式),您最好使用 Django formscleaned_data 来防止这些并发症。

【讨论】:

  • 谢谢你。我不使用 Django 表单,因为我认为这个简单的类选择没有必要。无论如何,一旦事情变得复杂,我会尝试表格。顺便说一句,你的名字听起来越南?我是越南人。
  • 嘿。 Tat nhien roi。 Minh la nguoi 越南Nhin cai ten la biet :) 很高兴在这里见到你,我的朋友 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多