'Django MEDIA not accessible

My Django app is unable to see MEDIA directory. When I run one of my views I need to open a file. The scenario is to:

  1. take a record with requested id from data base
  2. get the file path to a file
  3. send the file to external server for OCR purposes

urls.py

from django.conf.urls.static import static


urlpatterns = [
    #my urls
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)

models.py

from django.db import models
from django.contrib.auth.models import User

class Homework( models.Model):
    title = models.CharField(max_length = 200, default = None)
    image = models.FileField(upload_to='user_scans/')
    author = models.ForeignKey(User, default=None, on_delete = models.CASCADE)
    latex = models.TextField(default = "No LaTeX Here")

settings.py:

from pathlib import Path
from django.conf.urls.static import static

BASE_DIR = Path(__file__).resolve().parent.parent

...

DEBUG = True

...

STATIC_ROOT = BASE_DIR / 'static'
STATIC_URL = '/static/'
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = "/media/"

views.py

import requests
import json
from django.shortcuts import render, get_object_or_404
from .models import Homework

def create_homework(request):
    if request.method == 'GET':
        #some GET stuff
    if request.method == 'POST':
        homework = Homework()
        homework.title = title
        homework.image = image
        homework.author = author
        homework.save()
        id = homework.id
        json_to_mathsnip(id)

        ....

def json_to_mathsnip(id):
    homework = get_object_or_404(Homework, pk=id)
    f = open(homework.image.url, "rb")

    ...
    some later stuff
    ...

Unfortunately I'm constantly running into an error:

FileNotFoundError at /homework/new 

[Errno 2] No such file or directory: '/media/user_scans/kwa.png'

My main concern is I can access file from localhost:8000/media/user_scans/kwa.png and from admin panel. Requested file is saved properly:

file structure

Also settings.py configuration seems to be in tact. What might be the issue?

(env) $ pip freeze
asgiref==3.5.0
backports.zoneinfo==0.2.1
certifi==2021.10.8
charset-normalizer==2.0.12
Django==4.0.1
idna==3.3
Pillow==9.0.0
psycopg2-binary==2.9.3
requests==2.27.1
sqlparse==0.4.2
urllib3==1.26.9


Solution 1:[1]

This may not be the best way, but I tried it and it works. The bottom line is that when using the open() function with a relative path, such as /media/user_scans/kwa.png, then that file must be in the same directory as where the function is called. You could just find the absolute path of your image files in your computer, then append the filename to that and it will work, or you can do what I have below.

import requests
import json
from django.shortcuts import render, get_object_or_404
from .models import Homework

# ADD THESE
import os
from pathlib import Path

def create_homework(request):
    if request.method == 'GET':
        #some GET stuff
    if request.method == 'POST':
        homework = Homework()
        homework.title = title
        homework.image = image
        homework.author = author
        homework.save()
        id = homework.id
        json_to_mathsnip(id)

        ....

def json_to_mathsnip(id):
    homework = get_object_or_404(Homework, pk=id)
    # ADD THESE
    BASE_DIR = Path(__file__).resolve().parent.parent
    path_to_image_file = str(BASE_DIR) + homework.image.url
    f = open(path_to_image_file, "rb")

    ...
    some later stuff
    ...

When you show an image in Django, or you access its url, it is a relative path, but the root is the url root, localhost:8000/, and the image url is appended to that, and Django manages to find the file (how exactly, I don't know). But the image file is in your computer, and that is what you want to open.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1