Search code examples
djangomodelimagefield

The joined path is located outside of the base path component - Django image upload


I have a model with a ImageField. I want to upload the image to the folder media/item_image. Afterwards I want to be able to delete the image from the item, as well as the image file from the item_image folder. I was able to upload the image by altering the media root in the settings.py file, but I think this broke my delete function. Also it was not uploading the image in the right folder as intended.

Now I am trying it the other way around but I am getting the following error:

"The joined path is located outside of the base path component"

settings.py

MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'

models.py

class Item(models.Model):
    item_image = models.ImageField(upload_to='item_image', null=True, blank=True)

    def delete(self, *args, **kwargs):
        item = Item.objects.all()
        for i in item:
            i.delete()

        os.remove(os.path.join(settings.MEDIA_ROOT, self.item_image.name))
        super(Item, self).delete(*args, **kwargs)

I am a little stuck on how to approach this the right way. Is it because I am updating the Item instance and not deleting the instance? Does anyone have a clue?


Solution

  • Fixed it for the delete method and it is indeed because my custom delete function is based on deleting the item instance as a whole.

    settings.py -- defined MEDIA_ROOT after MEDIA_URL like so:

    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    

    models.py -- added the MEDIA_ROOT from settings and joined the folder item_image to it. Deleted the settings.MEDIA_ROOT and join path from the delete function os.remove like so:

    class Item(models.Model):
        item_image = models.ImageField(upload_to=settings.MEDIA_ROOT + '/item_image', null=True, blank=True)
        
        def delete(self, *args, **kwargs):
            items = Item.objects.all()
            items.delete()
            
                try: 
                  os.remove(self.item_image.name)
                  super(Item, self).delete(*args, **kwargs)
                except FileNotFoundError: 
                  pass
    
    

    Now when I add the image, it is placed correctly in the media/item_image folder. When I delete the complete instance it also removes the image file from the folder. When I only alter the the image field of the instance with a new file, the old file stays in place.

    Now i am working on a custom update function where the old image file is deleted and replaced with the new image file. Ideas on how to achieve this are more then welcome!