Using post_delete is definitely the right way. Sometimes, although everything may go wrong, and the files are not deleted. Of course, you have a bunch of old files that were not deleted before using post_delete. I created a function that deletes files for objects based on if the object reference file does not exist, then delete the object if the file does not have an object and then delete, it can also be deleted based on the "active" flag for object .. Something I added to most of my models. You must give it the objects you want to check, the path to the object files, the file field and the flag to delete inactive objects:
def cleanup_model_objects(m_objects, model_path, file_field='image', clear_inactive=False): # PART 1 ------------------------- INVALID OBJECTS #Creates photo_file list based on photo path, takes all files there model_path_list = os.listdir(model_path) #Gets photo image path for each photo object model_files = list() invalid_files = list() valid_files = list() for obj in m_objects: exec("f = ntpath.basename(obj." + file_field + ".path)") # select the appropriate file/image field model_files.append(f) # Checks for valid and invalid objects (using file path) if f not in model_path_list: invalid_files.append(f) obj.delete() else: valid_files.append(f) print "Total objects", len(model_files) print "Valid objects:", len(valid_files) print "Objects without file deleted:", len(invalid_files) # PART 2 ------------------------- INVALID FILES print "Files in model file path:", len(model_path_list) #Checks for valid and invalid files invalid_files = list() valid_files = list() for f in model_path_list: if f not in model_files: invalid_files.append(f) else: valid_files.append(f) print "Valid files:", len(valid_files) print "Files without model object to delete:", len(invalid_files) for f in invalid_files: os.unlink(os.path.join(model_path, f)) # PART 3 ------------------------- INACTIVE PHOTOS if clear_inactive: #inactive_photos = Photo.objects.filter(active=False) inactive_objects = m_objects.filter(active=False) print "Inactive Objects to Delete:", inactive_objects.count() for obj in inactive_objects: obj.delete() print "Done cleaning model."
Here is how you can use it:
photos = Photo.objects.all() photos_path, tail = ntpath.split(photos[0].image.path) # Gets dir of photos path, this may be different for you print "Photos -------------->" cleanup_model_objects(photos, photos_path, file_field='image', clear_inactive=False) # image file is default
radtek Jun 05 '14 at 23:22 2014-06-05 23:22
source share