models.FileField.path does not give correct file path

I have a model and it has a filefield to store background image for the object.

class MyModel(models.Model, ImageResizeMixin):
	background = models.FileField(upload_to='backgrounds/', blank=True, null=True)

	def save(self, *args, **kwargs):
		if self.background:
			self.resize(self.background, self.DEFAULT_BACKGROUND_SIZE)

# output

# actual path is /srv/media_root/backgrounds/image.png

On model’s save() method I resize the image, so it outputs a new file.
I no need original file after conversion so I want to delete it.
The problem is when I try to get path of the file, it does not give correct path.


It outputs /srv/media_root/image.png
But the actual image path is /srv/media_root/backgrounds/image.png
I am not sure why FieldFile.path gives wrong path.
Folder name specified by upload_to argument is missing.

Any help would be appreciated.

I believe the path attribute is not valid until you’ve saved the file. (I don’t think the final physical path can be known until after the storage backend has handled it, which occurs during the save.) So my understanding is that you need to call super().save(...) to save the file first, then you can get the physical storage path.

Hi @KenWhitesell
But let’s say that I saved an image already and I want to replace it.
So I uploaded a new file on django admin and in this case, I should delete previous file because we no longer need that file
I am not deleting current file.

If it’s a field for a file that has already been saved, then the path attribute should be good. But you’d want to access the existing instance from the database, not the instance created from binding the form.
(Actually, I don’t know off-hand if the Admin form makes the original data available - you might be able to save a query.)

I finally found the solution.
So on the save method, the self represents new object being updated or created.
So it has new image as you said.
So I had to fetch original object from db and got the correct path of previous file

def save(self, *args, **kwargs):

        this_object = Machine.objects.get(
        old_file_name = this_object.background.path