How to delete existing file when user uploads a new one
<p>I've just successfully implemented a method similar to the one that Giles suggested for saving new images with a filename of the primary key of the model here:
<a href="http://stackoverflow.com/a/16574947/5884437">http://stackoverflow.com/a/16574947/5884437</a></p>

<p>Actual code used:</p>

<pre><code>class Asset(models.Model):
    asset_id = models.AutoField(primary_key=True)
    asset_image = models.ImageField(upload_to = 'images/temp', max_length=255, null=True, blank=True)

    def save( self, *args, **kwargs ):
        # Call save first, to create a primary key
        super( Asset, self ).save( *args, **kwargs )

        asset_image = self.asset_image
        if asset_image:
            # Create new filename, using primary key and file extension
            oldfile = self.asset_image.name
            dot = oldfile.rfind( '.' )
            newfile = 'images/' + str( self.pk ) + oldfile[dot:]

            # Create new file and remove old one
            if newfile != oldfile:
                self.asset_image.storage.delete( newfile )
                self.asset_image.storage.save( newfile, asset_image )
                self.asset_image.name = newfile 
                self.asset_image.close()
                self.asset_image.storage.delete( oldfile )

        # Save again to keep changes
        super( Asset, self ).save( *args, **kwargs )

    def __str__(self):
        return self.asset_description
</code></pre>

<p>e.g. User submits "MyPicture.jpg" on a blank 'new asset' form. Server first pre-saves the new asset to generate an (asset_id) primary key, then renames the file as [asset_id].[original_extension] (e.g. "26.jpg") and moves it to the correct folder. </p>

<p>Unfortunately I've just found that this doesn't take into account files with different extensions, e.g. a user first uploads an image that gets renamed "26.jpg", but then when a user uploads a new image for that asset with a different extension (e.g. ".png"), both "26.jpg" &amp; "26.png" will be saved alongside each other.</p>

<p>How can I change this so that an existing image is always deleted when a new image is uploaded for that asset / primary key? </p>

<p>You can attempt to delete the old image when it doens't match the newly sumbitted image:</p>

<pre><code>class Asset(models.Model):
    asset_id = models.AutoField(primary_key=True)
    asset_image = models.ImageField(upload_to = 'images/temp', max_length=255, null=True, blank=True)

    def save( self, *args, **kwargs ):
        # Delete the old image
        try:
            asset = Asset.objects.get(id=self.id)
            if asset.asset_image and self.image and asset.asset_image != self.image:
                # Delete the old file if it doesn't match the newly submitted one
                asset.asset_image.delete(save=False);
        except Asset.DoesNotExist:
            # Do nothing when a new image is submitted
            pass
        # Call save first, to create a primary key
        super( Asset, self ).save( *args, **kwargs )
        ...
</code></pre>

<p>A better solution might be to take a look at <a href="https://pypi.python.org/pypi/django-cleanup" rel="nofollow">django-cleanup</a> which automatically deletes files for FileField, ImageField and subclasses. It will delete the old file on model deletion or when a new file is being updated.</p>

python django django-models