Django - Not Found The requested resource was not found on this server on Production

Viewed 36

I was trying to deploy my Django project on Render . Everything works fine except for the media files. I can't figure out the issue here.

I have added the followings into my settings.py:

DEBUG=False
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'accounts',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    "django.middleware.security.SecurityMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",
]

STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / "staticfiles"
STATICFILES_DIRS = [
    BASE_DIR / "static"
]

MEDIA_URL = '/contents/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/contents/')
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
STATICFILES_STORAGE = "whitenoise.storage.CompressedStaticFilesStorage"

urls.py

from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
        urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

I have created a Post (using models) before deploying. It had an image located a ./static/contents/Screenshot_334.png After deploying this image is accessible at https://someusername.onrender.com/static/contents/Screenshot_334.png . But if I create a new post from the deployed site I get a 404 error. The site doesn't cause any issue while its in the development mode.

Here's a portion of LOGS from Render: enter image description here

https://someusername.onrender.com/static/contents/Screenshot_334.png (created while development) is accessible but https://someusername.onrender.com/static/contents/Screenshot_1.png (created post-production) is inaccessible. Also, static files (css, js) working fine.

I checked all the files and directories using the following piece of code:

res = []
for path, subdirs, files in os.walk('./'):
    for name in files:
        res.append(os.path.join(path, name))

Screenshot_334.png and Screenshot_1.png both are in the same directory

I also tried switching MEDIA_URL and MEDIA_ROOT to 'contents', 'contents/', 'static/contents/' and all the possible variations.

UPDATE: I have found a workaround since I couldn't figure it out myself. I have mapped media to the urls.py and used FileResponse

Here's how views.py looks:

from django.http import FileResponse

def media(request, path:None):
    img = open('./contents/'+path, 'rb')
    response = FileResponse(img)
    return response

I'm aware this might cause security issues but I think it won't do me any harm since it is a project just for learning.

1 Answers

Add whitenoise in your installed apps

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'whitenoise',
'accounts',

]

then add whitenoise.middleware.WhiteNoiseMiddleware in your middleware right after the first line.

try configring the static files as below in your settings.py

STATIC_URL = 'static/'
STATIC_ROOT = BASE_DIR / "staticfiles"
STATICFILES_DIRS = [
    BASE_DIR / "static"
]

MEDIA_URL = 'contents/'
MEDIA_ROOT = BASE_DIR / 'static/contents'

edit your urls.py

from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
    path(....)
]
urlpatterns += static(settings.STATIC_URL, 
   document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, 
   document_root=settings.MEDIA_ROOT
)
Related