程序化保存图像到Django ImageField导致无尽图像循环
我有一个模型里面有个叫 save
的方法,代码大概是这样的:
def save(self, force_insert=False, force_update=False):
img_url = "http://example.com/%s.jpg" % (self.title)
name = urlparse(img_url).path.split('/')[-1]
content = urllib.urlretrieve(img_url)
self.image.save(name, File(open(content[0])), save=True)
super(Test, self).save(force_insert, force_update)
但是不知道为什么,这个方法导致了无限循环的图片创建,文件名里出现了越来越多的 _
。最后我发现是因为Django报了个错,提示说它试图保存的文件字符太多了(我发现保存了242张图片)。
我当时是想用 这个问题里的信息。
有人知道这是怎么回事吗?
2 个回答
0
我不是百分之百确定,但可能是当你调用 self.image.save
时,它默认也会调用模型的保存方法,这样就可能导致无限循环。我没有测试过,但我觉得有这个可能。
如果真的是这个问题,我的建议是:在模型的保存方法里发送一个信号,这个信号包含当前实例的信息,然后再用一个单独的函数来下载、解析图片并保存它。
6
我从源代码中看到,调用 ImageFileField.save()
(实际上是 FileField.save()
,因为它是继承来的)会导致存储文件名的实例(也就是数据库中的一行数据)被更新。
这意味着在你的 save
方法中调用 ImageFileField.save()
,而这个调用又会触发你自己的保存方法,从而导致了递归调用。
根据源代码,如果你想避免这种情况,只需在 self.image.save
中传递 save=False
。这样做会把文件数据保存到磁盘,但不会保存实例(数据库中的一行数据)。不过在下一行你通过调用父类的方法来保存,所以我认为这时数据会被保存到数据库中。
实际上,save=False
这个参数的设计就是为了处理这种情况的!