What I wanted to achieve was for a user to upload a file through a form, lets say profile picture,
My aim is to take that file, send it through imgbb's api and get the image url to store for use in my template later.
I was able to achieve this with the piece of code below, that works locally(Windows) but as soon as I push to my production server(pythonanywhere in this case), the code fails.
# CODE:
def testingpage(request):
image = ''
url = ''
if request.method == 'POST':
pic = request.FILES['image']
url = upload_to_bb(request, pic)
if url is not None:
from django.contrib import messages
messages.info(request, 'Uploaded Successfully')
return render(request, 'test.html', {'image': url})
def upload_to_bb(request, pic):
import os
from django.conf import settings
from django.core.files.storage import FileSystemStorage
import base64
import requests
base_url = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
fs = FileSystemStorage()
filename = fs.save(pic.name, pic)
file_path = f'{base_url}\media\{filename}'
apikey = settings.IMGBB_API_KEY
with open(file_path, "rb") as file:
url = "https://api.imgbb.com/1/upload"
payload = {
"key": apikey,
"image": base64.b64encode(file.read()),
}
r = requests.post(url, payload)
js = r.json()
if r.status_code == 200:
data = js['data']
file.close()
os.remove(file_path)
return data['image']['url']
else:
file.close()
os.remove(file_path)
from django.core.exceptions import ValidationError
raise ValidationError("An error occurred processing the image")
return None
the culprit is this line of code
file_path = f'{base_url}\media\{filename}'
On local windows server: It returns
C:\Users\Sammy\PycharmProjects\kegites\media\WIN_20211209_15_41_37_Pro.jpg
on pythonanywhere, I get the error:
FileNotFoundError at /
[Errno 2] No such file or directory: '/home/kegitesclub/kegites\\media\\WIN_20211209_15_41_36_Pro_3afnrPi.jpg'
on heroku , I get:
No such file or directory: '/app\\media\\WIN_20211209_15_41_37_Pro.jpg'
Is it something to do with linux, that these servers are or is it something else, perhaps a Django limitation?, or can you suggest a better approach to reach end result?
Any help would be appreciated
StackTrace for pythonanywhere:
Image link : https://i.stack.imgur.com/quXPI.png
CodePudding user response:
If you need to have system agnostic paths (between Windows and Linux environments) use os.path.join
or even better pathlib
to build them.
file_path = os.path.join(base_url, 'media', filename)
or in case of pathlib
base_url = pathlib.Path(__file__).resolve().parent.parent
and then
file_path = base_url / 'media' / filename
CodePudding user response:
try changing this line from this
file_path = f'{base_url}\media\{filename}'
to this
file_path = f'{base_url}/media/{filename}'
and test it in the server