Static files and Media files

Up until yesterday I only had my STATIC_URL and STATICFILES_DIRS in my settings since I wasn’t using a media directory (my understanding is media is for end-user uploaded files and static is for CSS, JS, and images, please correct me if I’m wrong). I set MEDIA_URL and MEDIA_ROOT and set my project up to allow end-users to upload files on a form. Now none of my images will display and I’m getting not found errors when the page loads

Not Found: /media/static/images/20210315_154336.jpg
[27/May/2022 08:21:33] “GET /media/static/images/20210315_154336.jpg HTTP/1.1” 404 5254

I noticed that the server is trying to get the images from /media/static/images/, however, I have separate static and media directories in my root. Should my static directory be in my media directory? Can I keep them separate? Later when I start using S3 will my media files upload to S3 also?

Settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / "media"
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    BASE_DIR / 'static',
    BASE_DIR, 'base/static'

Your understanding is correct.

Ideally, no. Those two directories should be completely separate.

That’s up to you.

How are you rendering these URLs in your template?

What is your STATIC_ROOT setting?

<a href="{% url 'base:property_details' slug=property.slug %}">
                                <img class="prop-image-scale" src="{{ property.thumbnail.url }}" alt="Property thumbnail">

The URLs are stored in my database
image

I don’t have a STATIC_ROOT setting.

Well, that explains why you’re seeing:

It’s prefixing the url in the database with the MEDIA_URL.

Note that that’s a URL and not (necessarily) a physical path. These would all be relative to whatever your file server is configured for as the root of that url.

In a production environment, ideally, neither your STATIC_ROOT nor your MEDIA_ROOT would be in the same path as your application. Your web server should be serving those files directly, not your application. So the configuration of your web server needs to be coordinated with the configuration of those settings in your application.

I figured that out. I’m just not sure why it’s prefixing media and not using my static directory.
.

What do you mean by this? The documentation and tutorials I’ve been following all seem to point the STATIC_ROOT and MEDIA_ROOT to the project root directory

Project
	App1
	App2
	media
         uploads
             documents
	static
         CSS
         JS
         Images
	venv
	Project

Am I not understanding the documentation correctly? Where should my STATIC_ROOT and MEDIA_ROOT be? Should all my images be moved to my media folder?

There are differences between development and production environments.

For development, it probably doesn’t matter much what you use.

For production, you want them to be separate. See the docs at How to manage static files (e.g. images, JavaScript, CSS) | Django documentation | Django

If you use the {% static tag, it’s a static file, based on STATIC_URL. If you’re using the url attribute of a file field, it’s a media file, and based on your MEDIA_URL. (It’s documented here: File storage API | Django documentation | Django and Managing files | Django documentation | Django)

Also see Deployment checklist | Django documentation | Django.

I don’t understand what you mean here. Are you talking about keeping static files separate by app and adding them to STATICFILES_DIRS?

This makes sense to me, in this case, based on my code what should I do? Just use the media directory for my images and store my CSS, JS, and hard-coded images in my static folder?

Edit
assuming I drop off the .URL off this tag wouldn’t that let the image load?

<img class="prop-image-scale" src="{{ property.thumbnail.url }}" alt="Property thumbnail">

I do something similar on a different page and that image will show but my property thumbnail doesn’t load on.

 <img class="homepageimage" src="{{ banner.image }}" alt="House at night">

You should have (at least) three separate and independent directories - one for staticfiles, which gets populated during your deployment process using collectstatic, one for media files which will get populated by files being uploaded, and your project directory containing your Django application. None of these directories should reside in any of the others.
(Our internal convention is that applications are placed in /home/<project name>, static files are collected into /var/www/html/<project name>, and media files are placed in /var/media/<project name> - with appropriate subdirectories in any of these as needed. nginx is configured to serve files in /var/media and /var/www, while uwsgi runs the applications in /home.)

That depends upon whether you’re talking about a development environment or a production environment - and how you’re running your application in each.
This isn’t a “one-size-fits-all” situation where you can be given a “do-this” answer and have it guaranteed to work. You need to gain the understanding of how the URLs being generated result in a request being handled by a server - and how to configure everything to work together. If your page is generating a URL like /media/static/images/abc.jpg, then you need to ensure that whatever web server you’re running knows how to retrieve abc.jpg from whatever directory in which it resides.

(Side note: Many people believe that deployment of a Django application is one of the most difficult tasks to perform. Getting everything working together can be extremely confusing.)

1 Like

I can 100% believe it. This has been the most confusing part.

Based off the documentation, my STATIC_ROOT should be STATIC_ROOT = "/var/www/example.com/static/" or STATIC_ROOT = staticfiles depending on what deployment I use? If that is correct, then I need to move my static files to their corresponding application directory? I only have 1 app currently so everything has just been in the root.

Okay that one seems simple enough

Are you referring to the folder that contains the ASGI, settings, and URL files?

Is this what the file structure should look like?

Project
	App1
       URLs.py
       views.py
       All_outer_app_files.py
       templates
	   static
           CSS
           JS
           Images
    App2
       URLs.py
       views.py
       All_outer_app_files.py
       templates
	   static
           CSS
           JS
           Images	
     media
        uploaded files
    staticfiles
        collection of all static files
	venv
	Project
        settings.py
MEDIA_URL = 'media/'
MEDIA_ROOT = BASE_DIR / "media"
STATIC_URL = 'static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_DIRS = [
    BASE_DIR / 'app1/static/',
    BASE_DIR, 'app2/static/'
]

As examples of what it might be set at, sure. But it’s really entirely up to you. There is no requirement on what it needs to be. As long as your web server is configured to serve static files from that directory, it could be anywhere.

Along with all the .py files of your project, yes. (e.g. models.py, views.py, apps.py, forms.py, etc, etc, etc) Basically, everything.

Your sample works, yes, except that I never recommend either STATIC_ROOT or MEDIA_ROOT refer to a directory within the project.

Do you mean you would back out 1 directory and put them there?

In our case, we use the structure described above. (Static files and Media files - #8 by KenWhitesell)