Fix all problems with Django, DRF, Serve static files, Images on Heroku when DEBUG=False with SQLite3

Viewed 464

I start learning Django, DRF about a few months ago. After finishing a simple eCommerce project I wanna deploy it on Heroku because it is free. But on Heroku, I got several problems as a beginner as usual. Serving static files, Images on Heroku when DEBUG=FALSE on setting.py file.

It takes about 1 week to solve how to do it properly without using any additional static or media files dedicated server (like AWS s3, Nginx, apache server). I read several StackOverflow articles, websites, Youtube videos, Django official website that how to serve static files but I did not get any proper solution.

Some link is here:

https://docs.djangoproject.com/en/3.2/howto/static-files/

https://docs.djangoproject.com/en/3.2/howto/static-files/deployment/

https://docs.djangoproject.com/en/3.2/ref/contrib/staticfiles/

above all links did not fix my issue

In Stackoverflow everybody says Django doesn't serve static files on production anymore when DEBUG=False. So you have to use this and that in this or that way. I try a lot but finally failed whether in the local development server or Heroku production server.

After that, A senior Django developer help to fix this. So I think it will help those who are in the same situation just stop using this way of serving images or static files:


 urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

 urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

# if settings.DEBUG:
#     urlpatterns += static(settings.MEDIA_URL,
#     document_root=settings.MEDIA_ROOT)

Use This way

urls.py

from django.conf import settings
from django.contrib import admin
from django.urls import re_path
from django.views.static import serve


urlpatterns = [
    path('admin/', admin.site.urls),

    re_path(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}), 
    re_path(r'^static/(?P<path>.*)$', serve, {'document_root': settings.STATIC_ROOT}),
    
]

settings.py (only important lines)


BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DEBUG = False



MIDDLEWARE = [
    #...
    'django.middleware.security.SecurityMiddleware',

    'whitenoise.middleware.WhiteNoiseMiddleware', # whitenoise
    #...
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'frontend/build')
        ],
]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
    os.path.join(BASE_DIR, 'frontend/build/static'),
]

MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # media files upload directory
MEDIA_URL = '/media/' # media files retrive directory

Some Django Heroku Deploying Rules

https://devcenter.heroku.com/articles/django-app-configuration

https://devcenter.heroku.com/articles/django-assets

Note: Heroku Image and static serving problem, Django version: 3.2 Python: 3.9.4

0 Answers
Related