关于python:Django – NullBooleanField不会保留自定义save()方法的False值

Django - NullBooleanField won't retain False value from custom save() method

刚来Django的人,如果我错过了一些明显的事情或者做了一些愚蠢的事情,请原谅我…

我有一个带有自定义save()扩展名的django模型。修剪不相关的字段和方法,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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提取器函数返回一个URL字符串和一个表示图像类型的布尔值:对于大于某个宽度的图像为true,对于较小的图像为false,如果找不到合适的图像,则为none。问题是,当我查询content.objects并检查image_type时,所有对象都返回true或none。因此打印语句。图像类型为"无"或"真"的图像按预期工作,但当图像类型返回"假"时,打印内容如下:

1
2
3
4
extractor returned:  False
before set:  None
after set:  False
from query:  True

无论如何,对super().save的调用总是在我尝试设置false时将image_类型恢复为true(但如果我不设置,则不会)。我承认,我不太了解super(),但是根据文档,在扩展模型函数时似乎有必要这样做。有人能解释一下这里发生了什么事吗?我该怎么解决?

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


自从写下这个问题以来,我提出了一个临时的解决方案,即使用integerfield将布尔值存储为0或1。在决定今晚重新审视这个问题并回到Nullbooleanfield之后,突然一切都按预期工作了。所以看起来丹诺诺万是正确的:上面的代码是正确的,不幸的是,我仍然不知道是什么导致了这个错误。我在使用integerfield时更改的其他内容一定解决了这个问题。多亏你们中的一些人看了一眼,提出了一些意见,我很抱歉浪费了你们的时间。


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

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

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

通过:

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

查看文档:https://docs.djangoproject.com/en/dev/ref/models/instances/pk属性

摘自Django文件:

Once the object has been saved, you must reload the object in order to
access the actual value that was applied to the updated field:

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

print(product.number_sold)

< /块引用>< /块引用>< /块引用>