Reputation: 17
I seem to be having an issue serving up media content on my website. Everything works fine when run on localhost. However, when deployed to python anywhere, I receive a FileNotFoundError when I attempt to upload an image via a form. I've taken a look through overflow for some related topics however I've not found any threads which have allowed me to solve my problem.
Here is the exact error received when submitting the image upload form:
It seems to be an issue with the resize method in models.py (which works fine on localhost)
Here are the appropriate setup files: settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
...
MEDIA_DIR = os.path.join(BASE_DIR, 'media')
# Media
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
IMAGES_DIR = os.path.join(MEDIA_URL,"images")
I believe the error is due to the images_path method not retuning the correct location (but it works on localhost). Here is the model which stores the image and defines how images are saved: models.py
class Image(models.Model):
# this might work?
def images_path():
return os.path.join(settings.IMAGES_DIR, 'usruploads')
def resize(self):
im = PIL.Image.open(self.image)
size=(200,200)
out = im.resize(size)
out.save(self.image.__str__())
def save(self, *args, **kwargs):
super(Image, self).save(*args, **kwargs)
self.resize()
image = models.ImageField(upload_to=images_path()[1:], max_length=255)
I will also throw in the media directory structure of the site in case this info is of use.
This is my first attempt at a deploying a Django web app via python anywhere so hopefully once this issue is fixed, it is a mistake I will never make again.
I have implemented the change you suggestd and the referenced url exists which is now a start however the server is claiming that it does not.
I have printed out the URL and path of the image as follows:
I can go to the index page and enter this url and it loads the image.
Ok, your suggestion was correct uring path instead of __str__() worked. The reason the issue second issue was occurring was then due to the fact that I was opening the image using url and trying to save it using path it did not like this. Thanks for your help!
Upvotes: 0
Views: 656
Reputation: 2919
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
IMAGES_DIR = os.path.join(MEDIA_URL,"images")
and
class Image(models.Model):
# this might work?
def images_path():
return os.path.join(settings.IMAGES_DIR, 'usruploads')
def resize(self):
im = PIL.Image.open(self.image)
size=(200,200)
out = im.resize(size)
out.save(self.image.__str__())
def save(self, *args, **kwargs):
super(Image, self).save(*args, **kwargs)
self.resize()
image = models.ImageField(upload_to=images_path()[1:], max_length=255)
We can infer that
IMAGES_DIR = "/media/images"
and
image = models.ImageField(upload_to='media/images/usruploads', max_length=255)
That means files are uploaded to /<base_dir>/media/media/images/usruploads
.
Looking at your logs, the error happens at the end of your logs.
...
out.save(self.image.__str__())
The issue is self.image.__str__()
returns the relative path/filename of the file, and when you pass a relative path to out.save
, it will try to save that file in the provided path RELATIVE TO THE CURRENT WORKING DIRECTORY.
What you have to do instead (assuming you want to replace the original image) is pass the absolute path of the original image:
...
out.save(self.image.path)
Upvotes: 1