Static Files
In this lesson, you’re going to learn about static files so you can add images, CSS, or JavaScript in the right folder structure inside Django.
When you created models.py
, you said that there would be images associated with each project and you put them in the database with the filepath '/img'
:
# Create your models here.
class Project(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
technology = models.CharField(max_length=20)
image = models.FilePathField(path='/img/')
Just like you saw with the templates
folder, Django is aware of all the static
folders inside each project and collects all of them and puts them all in one folder, so don’t forget to use double folder structure.
00:00 Hey again! In this video, we’re going to talk about static files: how to add images—or eventually also other things like CSS or JavaScript—into the right folder structure inside of Django. Let’s take a peek.
00:15
So, what we did in our models
before, we said there’s going to be images associated to each project, and we put them into the database with the file path '/img'
(image).
00:25
One thing you need to know about Django is that, similar to the templates folders, Django’s going to be aware of all the static/
folders inside of each project.
00:34
So, something that’s called static
inside of here—let’s go ahead and create it: static
.
00:39
Django’s going to know about that this exists, and it’s going to look for images, for example, inside of there. So, what we’re telling it here is we’re saying inside of static, there’s going to be a folder called img
. Let’s create that one as well.
00:58 And inside of there, we’re going to have the different file paths. Those are just going to be the names of our image files associated with the projects. Cool.
01:08
So, what we could do next is just copy-paste those images right in here, and then start hooking it up. However, what I mentioned for a moment was these static/
folders are similar to templates/
in that Django is aware of them inside of each app, and they are similar in another way, which is that in production, Django collects all the static/
folders from all of the apps that you have in your project together, and puts them all into one folder.
01:37
So remember, we looked at Django’s double folder structure when we looked at template folders. So we said, we want to put always a subfolder that has the name of the project inside of the templates/
folder, so that then, when they finally all get collected together in the big templates/
folder, we’re not going to run into any problems.
01:58
The same thing, surprisingly, applies also for everything inside of static/
. So what do we want to do again, to avoid future troubles, is to make this double folder structure.
02:09
Inside of projects/
, we’re going to have a static/
folder, and inside of there, we’re going to have another projects/
folder, named after the app that you’re working with. The reason the exact same as with templates/
: if it gets collected together, we want to avoid ambiguity.
02:23
So, eventually, this is what we would want to end up in production: one big static/
folder, a subfolder named after the app, and then inside, whatever we have, and then we can repeat ourselves and it’s not going to make any problems. Okay, so, this is not how we currently have it set up over here, all right?
02:43
We’re just saying static
—that’s the one that Django’s aware of—and then '/img'
. So we will have to change something here and let’s go ahead and fix that.
02:57
What we need to do is add here, the name of the project folder, projects
—
03:04
that’s how we want it to look like: '/projects/img'
. And then, inside of here, we’re going to recreate this same structure that we have with templates/
, so I’m going to make a new folder in here, call it projects
, the name of our app, and then I’m going to move this folder in there.
03:28 So now, perfect, right? Now we have the double folder structure, everything is fine. Inside of here, we’re going to have our images. However—and that’s an important thing to be aware of—we made a change to our model that is going to tell the database how to set it up, but we have not applied this change to the database.
03:48
So what we need to do to make these changes also be reflected inside of the database—so that every data item, every image
file path that we’re going to add, is actually going to have this extra projects/
folder prepended to it—is we going to have to do two things. First, we’re going to have to say python manage.py makemigrations
.
04:12 Let’s take a look at this. You’re going to see another migrations file pop up here, once I run this command,
04:20
and it also gives us feedback. It tells us, “Okay, what happened is we altered the field image
on project
.” project
is our table and that’s the image
field. We made a change here.
04:33 A way that you can see here, also, is a second migrations file popped up that has encoded in Python to translate into SQL, and then finally apply those changes to the database. Again, they’re not applied yet.
04:47
All we did with this first command makemigrations
is to make the migrations—in here, this file gets created. And now, what we want to do is apply those migrations to the database
04:59
by running the command migrate
. So, once I run this, we see a much shorter output than last time, but we get another OK
, so that means that now our database, every time we’re going to add something to it, it’s going to prepend '/projects/img'
, which is perfectly correct for how we want our double folder structure to be set up. All right. So, let’s close all of this.
05:22
We took a little excursion in here. What we want to do now, is to also add image files in here. Because all that we’re storing in our FilePathField
, is just the path to the files, not the files in themselves.
05:38 We’re going to have to add the files to this folder. And for that, I’m going to head to my desktop, where I have these three files randomly distributed around here, and I’m going to add those to my project.
06:24 So, after moving them over, now I have them sitting in here, just inside of the folder structure. We know that our path that we’re saving into the database is going to correctly bring us all the way to here, so that what we’re going to have to add is only the filename—depending on what entry we want to choose, the correct filename for that.
06:48 Perfect. That means our static files are set up and we can continue in the next video.
Martin Breuss RP Team on Oct. 24, 2019
Are you planning to make both apps part of the same webapp? I’d definitely suggest to name each app in your project with a unique name.
You could have two Django projects that both have an app each that is called projects. Then it shouldn’t cause any troubles and that’s what I’d suggest in your situation. If you really want both apps to be part of the same Django project, then they should have different names.
reblark on Oct. 25, 2019
Thank you. I do have two projects as I stated, but the video seemed to imply that somehow the double folder situation applied to all Django projects on your computer, so there would be a problem. I think there is some real confusion here about structure and hierarchy. From your comment here, it looks like I am ok because I have two different projects.
reblark on Oct. 25, 2019
I wonder what happened to my question about the image files? Where can we find those? How could we build this app without them? I would appreciate a response quickly as I have stopped progress waiting for an answer. By the way, what seemed to start out as rp-portfolio is now example-apps. Plus, three “unwatched” videos recently appeared in my table of contents. Is this a work in progress? Just wondering. I think it’s great that you are constantly improving the tutorial.
Martin Breuss RP Team on Oct. 26, 2019
Yes, if you’re working in two different Django projects, then you’re fine. The double-folder structure just applies to a single project. Different Django projects are separate from each other, and I’d suggest to create completely separate venv
s for them, too.
You posted your question regarding the image files in the following video and there’s an answer there.
As a note, it’s more effective to reach out on our Slack community when you are looking for some quick answers, since there are more people that can help you figure out how to get over a roadblock. The course creators won’t always be able to give you a speedy response on the comments here, so it’s a good way to go and reach out in multiple places and do your own research to avoid stalling your progress.
reblark on Oct. 30, 2019
Thank you for your responses as they are quite helpful. My experience with the “community” has been, well, less than satisfactory. Stack Overflow dosn’t like me and the feeling is mutual. I strongly believe that too many MOOCs or teaching sites abdicate the responsibility to help their students learn. It is a whole lot cheaper to just dump the questions out to the community which is full of phony “experts” or people with limited language skills. I could list a long number of MOOCs from Coursera to Pluralsight where I have tried to learn something and given up. Real Python is the best that I have found so far. There was one down in Florida which was bought and ruined by Pluralsight. People, individuals, in that company really felt a sense of responsibility to help people and they did. So, I will give the “community” a try but I have little hope.
Martin Breuss RP Team on Oct. 30, 2019
I’m sorry you had a couple of negative experiences with online learning sites. It can be tricky and really depends a lot on the values of the company and which people are involved.
I think that the Real Python community is a really welcoming bunch of people. :)
You could also check out Dan’s Pythonista Café that explicitly aims to be an inclusive, helpful, and welcoming peer-to-peer learning channel.
And you could take a look at CodingNomads, the company I’m working with, where we offer dedicated mentorship as a core part of our courses, because we believe that quality personal mentorship makes all the difference for learning something new.
reblark on Oct. 31, 2019
thanks Martin. I will check out Pythonista Cafe and Coding Nomads. How do I find the RP community?
Dan Bader RP Team on Oct. 31, 2019
How do I find the RP community?
Either by clicking on your avatar photo and selecting “Slack Community” from the menu, or by clicking this link :) More info here in our onboarding course.
reblark on Nov. 1, 2019
Great course, that onborading course. I have never ever seen one as good.
doronunu on Dec. 16, 2019
Where can i find the img files In to keep tracking this course?
Dan Bader RP Team on Dec. 16, 2019
@doronunu: When you go back to the first lesson in the course you’ll see a link where you can download the sample project as a zip file. The zip also includes the example images. Hope this helps you out :)
Lokman on Jan. 3, 2020
Actually how big img size we can add to our website?
Martin Breuss RP Team on Jan. 4, 2020
@VeLoct84 I am not aware of a size limit for images that you are displaying like this. You can think of them as images stored on your disk, and displayed in the browser with the help of Django.
Larger image sizes will, however, impact the performance of your website, especially when you are hosting it online. That’s because the users will need to receive more data over the network which means that the loading times of your site will be slower.
Lokman on Jan. 4, 2020
Larger image sizes will, however, impact the performance of your website, especially when you are hosting it online. That’s because the users will need to receive more data over the network which means that the loading times of your site will be slower.
Thanks for the explanation!
Amit kumra on Jan. 6, 2020
i am not able to create an object of Projeect class as i am working with command line console in windows and in Atom unable to work with Atom console.Kindly escalate the solution.
Martin Breuss RP Team on Jan. 7, 2020
Hello @Amit kumra. It is difficult to diagnose your issue and provide helpful tips without more information.
Can you describe what problem you are running into? Is there any feedback from your command line when attempting to create the object?
As some general tips:
- Make sure you are working in an activated virtual environment where you have Django installed
- Start the shell session with
python manage.py shell
- When creating the object, make sure you’re providing all the necessary information
Hope that helps, otherwise please describe in detail what you are doing and what is currently not working, as well as any error messages and exceptions you are receiving.
dinu on Feb. 26, 2020
Path for image is specified as “projects/img”. Shoudln’t it be “static/projects/img” instead.
Ricky White RP Team on Feb. 27, 2020
Hi Dinu. You don’t need to put static
at the start of your paths in this case, as Django knows to look for files and images there by default. This is because you will have STATIC_URL
set in your settings.py
file which tells it the base directory for all static file. Hope that helps.
tfgf on Dec. 10, 2020
Hi,
Python is throwing an error regarding FilePathField with path “projects/img” being not found.
Shouldn’t it be relative to double structure folder?
Like so:
image = models.FilePathField(path='projects/static/projects/img/))
tfgf on Dec. 10, 2020
Oh just realised that FilePathField error is handled at: realpython.com/lessons/debugging-part-1/.
Important: In case you try to fix it on this lesson, watch that video.
Vasanth Baskaran on Aug. 20, 2021
For those who are wondering, you can download the “sample project” zip file from the supporting material. If I am not wrong it contains the image files used by Martin on this course.
east4ming on Jan. 9, 2023
Is /static/img/projects/
more reasonable than static/projects/img/
? After all, a production web site typically has all the images under one context root (such as /img/
)
VitaminC on April 20, 2023
I’m using PyCharm Community edition. I noticed when you create directories in the “projects” folder that your IDE seems to create a package automatically without having to explicitly select a ‘package’ in the drop down list (New -> Directory). For me to create a folder represented by a folder with a small circle in it, such as you’ve done in your video, I have to select ‘package’ and not ‘directory’. Have you configured your PyCharm to do this automatically, or is it a feature that isn’t available on the Community edition?
Joshua Rin on Sept. 9, 2023
In the double-folder structure in the templates video you create templates/projects
, but in this double-folder structure you create static/projects/img
. I don’t understand the inconsistency.
Bartosz Zaczyński RP Team on Sept. 11, 2023
@Joshua Rin There’s no inconsistency, as both the templates/
folder and the static/
folder contain the corresponding app subfolders, such as projects/
. Inside that nested folder, you’re free to create as many subfolders as you like. The img/
one is a convenience folder to keep things organized by storing images separately from other static resources like JavaScript files or CSS styles.
Become a Member to join the conversation.
reblark on Oct. 24, 2019
in order to try to find some errors, I have done two implementations of this tutorial, having two projects, one called Django-portfolio and the other called Django-polls (from the Django website tutorial). Now, with this particular description of the double folder structure, it looks like I will have a problem with the app created in both projects named “projects.” Is that true? I am going to stop working on “Django-polls” until I hear from you. Thank you.