1

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

如果我尝试设置 False(但如果我设置 None),对 super().save 的调用总是会将 image_type 恢复为 True。我承认,我不太了解 super() ,但是根据文档,扩展模型功能时似乎是必要的。谁能解释这里发生了什么,以及我该如何解决?

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

4

2 回答 2

1

自从写了这个问题以来,我已经采取了一个临时解决方案,即使用 IntegerField 将布尔值存储为 0 或 1。在决定今晚重新审视这个问题并切换回 NullBooleanField 时,突然一切都按预期工作。所以看起来 danodonovan 是正确的:上面的代码是正确的,不幸的是我仍然不知道是什么导致了错误。我在使用 IntegerField 时更改的其他内容必须解决了该问题。感谢那些看过并提供一些意见的人,很抱歉浪费了您的时间。

于 2013-05-06T01:12:48.023 回答
0

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

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

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

通过那个:

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

查看文档:https ://docs.djangoproject.com/en/dev/ref/models/instances/#the-pk-property

从 django 文档中提取:

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

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

打印(product.number_sold)

于 2013-04-30T09:35:51.493 回答