cr_untilted
cr_untilted

Reputation: 45

Django is not loading media files on shared hosting cPanel

I am having issues loading media files uploaded by the user and displaying them via a template.html file when DEBUG = FALSE. The static files are displayed but I keep getting webaddress/media/images/image1.png 404 Not Found whenever I load the page. I followed some guides and added urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) to my urls.py but I am still getting the 404 error. I've chatted with the cPanel hosting provider and they said I do not have access to modify the cPanel Apache httpd.conf file so I am looking to have Django manage the serving of the media files since it handles the uploading of images to the media/images directory.

Location where images directory is: /home/<cPanelUserName>/repositories/djangoApp/media/images

settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
template/index.html

<body style="background: url('{{ background_pic.url }}'); background-size: cover; background-position: center; background-attachment: fixed;">
    <div id="profile">
        <img id="userPhoto" src="{{ profile_pic.url }}" alt="{{ profile_pic_title }}">
    </div>
</body>
models.py

class profilePic(models.Model):
    title = models.CharField(max_length=50)
    image = models.ImageField(upload_to='images/')

class backgroundPic(models.Model):
    title = models.CharField(max_length=50)
    image = models.ImageField(upload_to='images/')
views.py

def index(request):
    imageModel = profilePic.objects.get(pk=1)
    backgroundModel = backgroundPic.objects.get(pk=1)

    return render(
        request,
        "template/index.html",
        {
            "profile_pic_title":imageModel.title,
            "profile_pic":imageModel.image,
            "background_pic_title":backgroundModel.title,
            "background_pic":backgroundModel.image,
        }
    )
urls.py

from django.contrib import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns = [
    path('', include('SocialLinks.urls')),
    path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Upvotes: 1

Views: 1214

Answers (2)

Showkat Ali
Showkat Ali

Reputation: 23

I am not sure if it will work for you. But worked for my cPanel shared hosted Django Project. My procedure is as follow (Assuming DEBUG is set to False, and the server is apache):

1# In settings.py file

...
MEDIA_URL = 'media/'
MEDIA_ROOT = BASE_DIR / 'media'
...

2# In root urls.py file

...
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [ 
 ...
 ...
]

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

3# In .htaccess file (Where to find? explained below)

# DO NOT REMOVE. CLOUDLINUX PASSENGER CONFIGURATION BEGIN
PassengerAppRoot "/home/<username>/<site_directory_name>"
PassengerBaseURI "/"
PassengerPython "/home/<username>/virtualenv/<site_directory_name>/<python_version>/bin/python"
# DO NOT REMOVE. CLOUDLINUX PASSENGER CONFIGURATION END


#****************************************************
# Enable Rewrite Engine
RewriteEngine On

# Serve media files
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^media/(.*)$ /home/<username>/<site_directory_name>/media/$1 [L]
#****************************************************



# DO NOT REMOVE OR MODIFY. CLOUDLINUX ENV VARS CONFIGURATION BEGIN

<IfModule Litespeed>
</IfModule>
# DO NOT REMOVE OR MODIFY. CLOUDLINUX ENV VARS CONFIGURATION END

Now restart the server.

This might work. Now Explaining the code snippets:

for #1, it is just normal configurations for media files.

  • MEDIA_URL = 'media/' means our media files urls will have the string media after domain name and before the file path. For example, suppose your domain name is example.dom. if a image file named my_image.jpg in the post_images directory under the root media files directory named media, the URI for the image will be https://example.com/media/post_images/my_image.jpg and here, the part: media is from MEDIA_URL. so if MEDIA_URL were set as follow: MEDIA_URL = 'media_files/', then the image URI would be https://example.com/media_files/post_images/my_image.jpg.

  • MEDIA_ROOT = BASE_DIR / 'media' means, in our project directory, there is a directory named media at the same level where manage.py file resides. This directory will contains all the media files. So, if you have the different directory name for this, you update MEDIA_ROOT = BASE_DIR / '<your_media_root_directory_name>.

for #2, it is just normal configurations for development server to serve media files
When in your development server and DEBUG = True, you probably don't have the apache server. So it is django's default server. And you will need to specify how you want django to serve media files. applying this line with the if condition, you are telling django to serve media files by django. And if DEBUG is not True then you are not asking django to serve media files. Because it will then served by apache web server.

for #3, it is (.htaccess) is apache configuration file.

You can find this directory in the project directory. But since it has a dot . before the filename, it might be hidden by default for cPanel. You should unhide all the hidden files first if you want to work through the file manager. otherwise in terminal and a text editor like vim you can just find it by ls -a command. Anyway to work in file manager, you click on the settings at the upper-top of the window, then there is an option Show hidden files (dotfiles), where you must check then save. now you will see the .htaccess file and some codes will already be there. You then update this file as given above.

Thats how my problem were resolved. I don't expect you no longer needed this support. But I think, since even yesterday searched on the web and came here but got no solutions, someone like me might come here. And for that someone, I am answering this.

Upvotes: 1

Abdullokh Alimov
Abdullokh Alimov

Reputation: 61

Changing your media root path to the public_html folder should help you (on shared hosting cPanel)

before (you have media files inside your project directory)

 MEDIA_ROOT = '/home/{username}/{project}/media' ✖️

after (now they are stored inside public_html folder)

 MEDIA_ROOT = '/home/{username}/public_html/media' ✔️

Upvotes: 3

Related Questions