djangodjango-file-upload

django file opens locally but fails in server


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:

The stacktrace, it displays weirdly with copy/paste

Image link : https://i.sstatic.net/quXPI.png


Solution

  • 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