Django - NullBooleanField不会保留自定义save()方法的False值

时间:2013-04-30 02:33:09

标签: python django super

Django的新人,如果我错过了一些明显的东西或在这里做了些蠢事,请原谅我......

我有一个带有自定义save()扩展名的Django模型。修剪不相关的字段和方法,它看起来像这样:

class Content(models.Model):
    url = models.URLField(max_length=1000)   
    image = models.URLField(blank=True, max_length=1000)
    image_type = models.NullBooleanField(default=None)

    def save(self, *args, **kwargs):
        if self.url:
            img, img_type = image_extractor(self.url)
            print 'extractor returned: ', img_type
            print 'before set: ', self.image_type
            setattr(self, 'image', img)   
            setattr(self, 'image_type', img_type)
            print 'after set: ', self.image_type

        super(Content, self).save(*args, **kwargs)
        print 'from query: ', Content.objects.get(url=self.url).image_type

image_extractor函数返回url字符串和表示图像类型的布尔值:对于大于特定宽度的图像为True,对于较小图像为False,如果未找到合适的图像则为None。问题是,当我查询Content.objects并检查image_type时,所有对象都返回True或None。因此,印刷声明。具有image_type None或True的图像按预期工作,但是当image_type返回False时,这就是打印的内容:

extractor returned:  False
before set:  None
after set:  False
from query:  True

以某种方式调用super()。save总是将image_type恢复为True,如果我尝试设置False(但如果我设置None则不会)。我承认,我不太了解super(),但基于文档,在扩展模型函数时似乎是必要的。任何人都可以解释这里发生了什么,以及我如何解决它?

编辑:我注意到我可以通过管理页面将值更改为False并保持为False。但我仍然需要修复save()方法。现在,我刚刚用整数字段替换了布尔字段,并将值保存为0或1,这确实有效。但我仍然想知道为什么更合适的领域没有。

2 个答案:

答案 0 :(得分:1)

自写这个问题以来,我已经开始使用IntegerField将布尔值存储为0或1的临时解决方案。在决定今晚重新访问问题并切换回NullBooleanField时,突然一切都按预期工作。所以似乎danodonovan是正确的:上面的代码是正确的,不幸的是我仍然不知道导致错误的原因。使用IntegerField时我改变的其他东西必须解决了这个问题。感谢那些看过并提出一些意见的人,我很抱歉浪费你的时间。

答案 1 :(得分:0)

重载保存方法的方式看起来不错。 我认为你没有从数据库加载好的对象。 使用主键可能会更好。

在您的情况下,只需替换:

Content.objects.get(url=self.url).image_type

由此:

Content.objects.get(pk=self.pk).image_type

查看文档:{​​{3}}

从django文档中提取:

  

保存对象后,必须重新加载对象   访问应用于更新字段的实际值:

     
    
      
        

product = Products.objects.get(pk = product.pk)

                 

打印(product.number_sold)