tags:

views:

130

answers:

2

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(img_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?

A: 

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.

Bartek
+1  A: 

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!

Nick Craig-Wood
That did the trick. Thank you!
Trey Piepmeier