ss7
ss7

Reputation: 3012

Django Delete and Move Uploaded Files when Model Deleted

I have this code for when my model is deleted so that the files are deleted too. I also want it to move the files to a folder only the admin can see right before they are deleted.

Here is my code:

@receiver(post_delete, sender=ClientUpload)
def clientupload_postdelete(sender, instance, **kwargs):
    if instance.file:
        #with f as open(settings.MEDIA_ROOT + '/uploads/Recycle/' + instance.file.name, 'w+'):
        #   f.write(instance.file)
        #   f.close()
        #   logger = logging.getLogger(__name__)
        #   logger.info("File %s moved to %s" % (instance.file.name, settings.MEDIA_ROOT + '/uploads/Recycle'))
        # Pass false so FileField doesn't save the model.
        instance.file.delete(False)
    else:
        logger = logging.getLogger(__name__)
        logger.warning("Failed to find file %s for deletion." % instance.file.name)

The commented out parts are commented out because they were raising this error:
SyntaxError: Can't assign to function call. On the line with f as open(...). I'm not sure why, but that is supposed to be the part where it saves the file into another directory before deleting it. What am I doing wrong here? How can I write the file to another directory before I delete it?

Also is postdelete correct here or should I use predelete?

Finally, is instance.file.name the correct way to get the file's name in this situation? Or will just instance.file do the job? This is the first signal I've done so I am unsure and even with the documentation I'm having trouble getting it to work.

A small example would work wonders, thanks in advance

Upvotes: 0

Views: 306

Answers (1)

Agustín Lado
Agustín Lado

Reputation: 1095

What error were you getting exactly? "SyntaxError: can't assign to function call"? Because the with syntax is wrong. You're trying to assign f to open(), when it's the other way around:

with open(settings.MEDIA_ROOT + '/uploads/Recycle/' + instance.file.name, 'w+') as f:
# ...rest of the code

Try that change, and next time please post the Traceback to make debugging easier for us.

As for the signal type: post_delete is fine. The instance you're getting is no longer on the DB but contains the info you need (the file).

As for the question regarding instance.file.name, today I expected .name to return only the filename but it didn't. The way I got the filename was using os.path.basename. But in your case it's unnecessary

import os

filename = os.path.basename(instance.file.path)

Upvotes: 2

Related Questions