'Django DEBUG=False won't upload files to STATIC_ROOT

I'm trying to give the user the ability to upload images on a website I created with Django and the images are uploaded fine when running with DEBIG=True but the issue is that when DEBUG=False the image files doesn't upload to the MEDIA_ROOT instead it gets uploaded to STATIC_DIRS. Also, even the files that are already in MEDIA_ROOT after executing python manage.py collectstatic aren't loaded to the template and the image URL gives the 404 Page Not Found error.

The CSS and JS files are still served so it means only the media url isn't working.

Following are the codes I'm using.

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('Home.urls')),
    path('account/', include('Account.urls')),
]

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

settings.py

STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

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

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'static')

STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'

Note that I'm using whitenoise as the storage backend.

Here is the model code that is used to upload the file.

@deconstructible
class PathAndRename(object):
    def __init__(self, sub_path):
        self.path = sub_path

    def __call__(self, instance, filename):
        ext = filename.split('.')[-1]
        filename = '{}.{}'.format(uuid4().hex, ext)
        return os.path.join(self.path, filename)

rename_pp = PathAndRename('img/profile-pictures')

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
    avatar = models.ImageField(upload_to=rename_pp, blank=True, null=True, default='img/profile-pictures/default-profile-pic.png')

    def save(self, *args, **kwargs):
        super(Profile, self).save(*args, **kwargs)
        image = Image.open(self.avatar.path)
        if image.width > 100 or image.height > 100:
            output_size = (100, 100)
            image.thumbnail(output_size, Image.ANTIALIAS)
            image.save(self.avatar.path, file_quality=100)


Solution 1:[1]

When using DEBUG=True it means that you are at development side thus your local machine is able to serve the files (media files) but with DEBUG=False it is taken like you are now on deployment side.

To serve media files from that, you need to have a bucket(like amazon S3) which will store those files and will get served from there.

So if your media files are working fine when DEBUG=True, that means it is fine.

Now all you need is a place to store them.

Solution 2:[2]

I've used this instead of your STATICFILES_STORAGE and when debug=False everything works fine.

STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'

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 Irfan wani
Solution 2 omegabuz