Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Create a Template

In this lesson, you’re going to create a template for your Django app so you won’t have to paste all your HTML directly into your views. Django has already provided you with the import statement you’re going to need for this:

Language: Python
from django.shortcuts import render

Now that you have render(), use it in your function with the template name 'projects/index.html':

Language: Python
# Create your views here.
def project_list(request):
    return render(request, 'projects/index.html')

Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Already a member? Sign-In

Locked learning resources

The full lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Already a member? Sign-In

00:00 In this video, we’re going to go ahead and create a template for our Django app, to improve on not having to paste all the HTML directly into our views.

00:12 This is what we’ve been doing so far. I took away this whole bunch of HTML that we had before and just put back our little message. But what we’ve been doing is essentially pasting HTML directly into our view.

00:25 Now, we want to avoid this and instead, we want to render a template. So, Django gives us already in the views— because this is the common way of doing it—it already gives us this import statement that we’re going to use.

00:39 I’m going to get rid of this, and instead, I’m going to return this render() function. Let’s take a look at this again.

00:49 We’re going to need a template_name and then there’s some other things that default to None—so we’re just not going to worry about those for now—but we’re going to need to pass a request and the template_name.

01:02 So, the request I mentioned before is this Django object that keeps getting passed around because it contains a lot of helpful information.

01:10 So I’m just going to pass this again to render(), as requested, and then we’re going to also pass in a template_name. I’m going to name this template, let’s say… We’re inside of our projects app, so I’m gonna say 'projects' and then 'index.html'.

01:36 Okay, so we don’t need this anymore, but instead, now we’re rendering a template. What’s our server doing? Something changed, reloading, no complaints. Let’s take a look into the browser. What if I reload this?

01:56 Ooh, look at that. We get a new friend! This one’s called TemplateDoesNotExist at /projects/. So, it’s telling us very clearly that this template does not exist.

02:10 We’re going to have to do something. Where is it looking? It’s looking at projects/index.html. Okay, cool. So, this gives us already some kind of hint on how to do this, but the main thing is that we’re going to know Django understands we’re pointing to a template. It can’t find this template.

02:28 It’s just not there, so let’s go ahead and create it.

02:35 The standard in Django for doing this is that inside of your app, we’re going to create a new folder called templates.

02:47 Then, inside of here, another new folder that we give the same name as our app. In this case, it’s going to be projects. You might wonder, “What’s this weird double folder structure?” and I’m going to talk about this in just a moment.

03:01 Let’s finish up solving this error message before. So we have now projects/, this is this folder, okay, projects/. And then we need, inside of there, index.html. So, making a new file:

03:17 index.html. Cool! So, PyCharm already creates this HTML basic structure so that we don’t have to worry about this. Otherwise, you just type it out. In this case,

03:33 that’s what we’re going to say here, and take a look what our server is saying. It’s doing fine, a GET request, no complaints here. So we head back over to our browser and reload the page, and we’re still getting a TemplateDoesNotExist.

03:52 Let’s figure out why is that the case. And the reason for it is that we have not registered this templates/ folder. So, sometimes Django does this by default, that it finds all the templates/ folders inside of all the projects, but if you’ve set it up like this and you keep getting the TemplateDoesNotExist error, as we do right here, we’re going to have to go forward and register it.

04:21 This is our second excursion into the settings.py file. Similar to how we have INSTALLED_APPS, we can zoom around and then we find a setting that’s called TEMPLATES. Inside of TEMPLATES, there is a key called 'DIRS' (directories), and this is where we want to register our new templates/ folder.

04:45 For making this easier, I’m going to utilize a variable that we have in here called BASE_DIR (base directory). It’s defined up there and it just tells us the root of our Django project, so I can utilize that to from there navigate to a different path.

05:02 It makes it a little easier. So, heading back to—here we are—heading back to this 'DIRS' folder, I’m going to add here os.path.join()

05:18 just to create a proper path—and then here, I’m going to say BASE_DIR and hook it together with what we’re calling 'templates/projects'sorry, BASE_DIR, 'projects/templates'.

05:54 So, let’s see whether that solved our issue. We head back over here, reload this. Sometimes this happens, you just have to wait for the server to restart. Try it again, and here we are.

06:08 So now, Django can find our template because we told it where to look. We just told it to look relatively from our base directory inside of our projects app, and then inside of the templates directory. Cool.

06:21 So, if you set up everything as you expect it and it’s not finding it, head over to your management app inside of the settings file, find the 'DIRS' and then just add—you can just copy-paste this, and then just change whatever is the name of your app. It should be able to find it afterwards.

06:40 All right! So, now we could go in here and add whatever HTML we want, and we have a nicer separation between the views, where we’re now simply just pointing to this template, an actual HTML file Django template where we can write tons and tons of HTML, as much as we want to, as well as some Django templating language, which we’re going to look at later on. Before we move on, though, in the next video, we’re going to take a quick look about why do we want to have this weird double structure? We’re inside of projects/, we make a templates/ folder, we make another projects/ folder, and only then we place our template in there.

07:22 So, see you in the next video where we’re going to talk about why this is a good thing to do.

Avatar image for seangoodman37

seangoodman37 on May 9, 2022

Im really enjoying this great module thanks. When i added the code below i got an error. However, i actually didnt need to add the following as mine worked fine without it. Thanks

TEMPLATES = [ { “DIRS”: [os.path.join(BASE_DIR, “projects/templates”),] } ]

Avatar image for Martin Breuss

Martin Breuss RP Team on May 9, 2022

@seangoodman37 there’s been an update in how Django handles paths since we recorded this tutorial.

There’s an in-depth explanation in a comment a little further up, hope that helps.

Avatar image for stehnacheric

stehnacheric on Nov. 10, 2022

Hey, I was able to get everything to work but I got an additional warning from pylint that I was curious about. Warning (severity 8 whatever that means):

"message": "Module 'projects.views' has no 'project_list' member",

However everything is functioning correctly and I do have:

from django.http import HttpResponse
from django.shortcuts import render

def project_list(request):
    return render(request, 'projects/index.html')

in my project.views. Curious what this is and what effect it could have in the future.

Avatar image for simma99

simma99 on May 14, 2023

Hi. When I tried registering the templates folder in the settings.py page, I was getting os not found error. Then I checked the settings page completley. In my page it didn’t have the import os command predefined and the Base_DIR line was different. Can you please help (Plus I am using VScode as editor)

Avatar image for Martin Breuss

Martin Breuss RP Team on May 15, 2023

@simma99 like mentioned earlier, there’s been an update to Django that changed OS operations to using pathlib instead of os.

You can read more in an in-depth comment further up.

Avatar image for simma99

simma99 on May 19, 2023

@Martin Breuss thanks for the help. It worked without defining anything in the DIR and keeping APP DIR True.

Avatar image for Pat Peters

Pat Peters on Aug. 22, 2023

BASE_DIR = Path(__file__).resolve().parent.parent

'DIRS': [Path.join(BASE_DIR, 'projects/templates')]

This is not working, do I need something else in my base directory?

Avatar image for Pat Peters

Pat Peters on Aug. 22, 2023

Nevermind, I did not see the explantion above. Thanks.

Avatar image for marksemmelbeck

marksemmelbeck on Jan. 15, 2024

I am using VS Code, Django version 5. When I left the project and returned, I activate my environment and then run “python manage.py startapp projects”. I got the error “CommandError: ‘projects’ conflicts with the name of an existing Python module and cannot be used as an app name. Please try another name.”

I searched for the cause of this and the solution I found was to change the name of my project. I did to “myprojects”. This worked for a few days. I return to the project today and am receiving the same error, now for “myprojects”.

I know I should not have to change the name of the project again. There is something else. Should I not have run startapp again? What are the steps I should take when I leave this project, work on something else and then return? Thank you.

Avatar image for Martin Breuss

Martin Breuss RP Team on Jan. 17, 2024

@marksemmelbeck every time that you run startapp, Django tries to create a new app. Because you’ve already created an app with the same name (first projects, then myprojects), the command fails with the message that you mentioned. Python calls your app a “module” in the error message, which might be confusing. It is a module, so the message is correct, but if you think of it only from a Django perspective, then it might be more straightforward if the message read something like this instead:

CommandError: ‘projects’ conflicts with the name of an existing Django app in your project. Please try another name.

All that running startapp does is to create the app’s folder structure. You already got that after running it the first time, so you don’t need to run that command again unless you want to create a different app.

The steps you need to take when returning to the project after you’ve worked on something else are:

  • Activate your virtual environment (if you’re using one)
  • Run python manage.py runserver, which starts the development server

That’s all : )

Become a Member to join the conversation.