Programatically saving an image to a Django ImageField is creating an infinite loop of images
I've got a save
method on a model that looks like so:
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(i开发者_开发百科mg_url)
self.image.save(name, File(open(content[0])), save=True)
super(Test, self).save(force_insert, force_update)
For some reason, this is creating an infinite loop of image creations with ever more _
s in the filename. I finally figured out it was doing that when I got a Django error that said that the file it was trying to save had too many characters (I found 242 images saved).
I was trying to use information from this question.
Any idea what's going on here?
I think from a browse through the source code that calling ImageFileField.save()
(actually FileField.save()
due to inheritance) causes the instance (namely the db row) that the file name is stored in to be updated.
This means that in your save
method you call ImageFileField.save()
which in turn calls your save method, causing the recursion.
From reading the source code, if you want to prevent this, then just pass save=False
to self.image.save
. This will save the file data to disk, but just won't save
the instance (db row) data. However in the next line you save it by calling the superclass, so I think it will be saved to the database then.
In fact it looks like that the save=False
on the save
method was designed to help with this case!
I'm not 100% certain, but it could be that when self.image.save
is called, it calls the save method of the model, by default, as well - Thus creating your infinite loop. I haven't tested it but I could see that happening.
My suggestion if that is the issue: Send a signal from within the models save method containing that instance and then have a seperate function to download/parse the image and save it.
精彩评论