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

Unlock This Lesson

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:

from django.shortcuts import render

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

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

Django With pathlib

Newer versions of Django use the pathlib module instead of the os module:

# portfolio/
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

You can read over a detailed discussion of the changes in the lesson comments and learn more about pathlib.

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 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.

Gascowin on Oct. 19, 2019

May i ask; why is it that in you have

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

instead of

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

? My understanding here is that we are passing in the path to the file index.html and since and the templates folder are in the same directory we would need the path ‘templates/projects/…’ instead of ‘projects/…’ Thanks in advance.

Martin Breuss RP Team on Oct. 19, 2019

Great question! You are completely right in that we are pointing Django to the location of the index.html file.

The reason we don’t need to spell out templates, is that Django by default searches for your HTML files in a templates folder, where it aggregates all the templates from your whole project.

I talk about it some more in the video about Django’s Double-Folder Structure, but essentially the reason is that templates is defined as Django’s default location for templates and therefore doesn’t have to be explicitly mentioned.

reblark on Oct. 30, 2019

I have checked my code and tried this several times but consistently get the error that “projects/index.html” does not exist. But it does and it is in the templates/projects folder. I thought at first it was like your experience in the video that the file had not been registered, but surely it’s registered after all these attempts. Here is the template-loader-postmortem: Django tried loading these templates, in this order:

Using engine django:
django.template.loaders.filesystem.Loader: /Users/reb/Django/Django-CA/projects/templates/projects.index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /Users/reb/Django/Django-CA/rbvenv/lib/python3.7/site-packages/django/contrib/admin/templates/projects.index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /Users/reb/Django/Django-CA/rbvenv/lib/python3.7/site-packages/django/contrib/auth/templates/projects.index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /Users/reb/Django/Django-CA/projects/templates/projects.index.html (Source does not exist)

The file is there!

Dan Bader RP Team on Oct. 30, 2019

@reblark Looks like you might have a typo in the code somewhere where you’re referencing that index.html file:


Instead of projects/index.html it says projects.index.html (. instead of /).

reblark on Oct. 31, 2019

Hi Martin, Again, thanks for the response and suggestions but I need to tell you a little story. I looked at my code many, many times this morning and thought it was right. I could not find a mistake. So, I took a break and on the break, I tripped and busted my knee cap. I spent the next several hours in the ER. I came back discouraged, but after resting awhile, started this video over again. In the very first code presentation, views, I found the mistake. I couldn’t believe it. I made a simple change and ‘voila,’ it worked. I don’t know what to make of this. Maybe I just don’t have what it takes to be a programmer. I make too many mistakes and too many times I just can’t see those mistakes no matter how hard I look. However, if I continue, I believe that programming well will teach me something and improve my discipline. Thanks again for your graciousness.

Martin Breuss RP Team on Oct. 31, 2019

Don’t give up! Everyone runs into these situations where you just can’t find the error. Taking a break and coming back to it in a bit is often the best way to tackle it. I’d suggest to avoid trips to the ER, though if possible–there are definitely more fun ways to take a break!

Glad you figured out your error, and most importantly I hope everything’s alright with your knee!

Keep up the work if you find it interesting. Learning to program can definitely be a great asset in many ways. :)

reblark on Nov. 1, 2019

I don’t believe this. The response from Dan Bader was exactly right. It took me a day to find it, but I did find. I just saw Dan’s response for the first time and I am so impressed that someone actually answered my question. I think in my long missive whining about MOOCs I mentioned a company in Florida that was bought by Pluralsight who had a guy who as absolutely great at answering questions. I’ll be doing more courses with Real Python. I might learn something.

eclaudio on Dec. 2, 2019

I just attempted to push this group of files up to GitHub and had over 4518 files that are about to push. Is this correct? And if not, what did I do wrong?

Martin Breuss RP Team on Dec. 3, 2019

Hello @eclaudio. You probably committed your whole Virtual Environment to GitHub. To avoid pushing all these files, you should add your .env to your .gitignore file.

eclaudio on Dec. 3, 2019

@MartinBreuss 1. Thank you 2. the detail is great.

If we are using the above project as the file structure, where is the best place to create my .gitignore file?

eclaudio on Dec. 3, 2019

You Guys ROCK!!!

Martin Breuss RP Team on Dec. 3, 2019

.gitignore should be always right in the base folder where you initiated your repo with git init.

And thanks! You rock 🚀! :))

eclaudio on Dec. 4, 2019

@MartinBreuss yup it worked thank you!!

Martin Breuss RP Team on Dec. 7, 2019

Great that it worked! I’d suggest to keep the .gitignore file one level higher, in your django-portfolio folder. That should be the root folder of your project. However, it looks like it’s now on the same level as your file?

josemariapolanco on Dec. 25, 2019

Why can’t we specify projects.templates inside of TEMPLATES in It looks a lot cleaner than what’s suggested in the video.

Martin Breuss RP Team on Dec. 29, 2019

You can specify what templates Django looks into in in the TEMPLATES list in the DIRS list. Here’s more to read about it in the official docs. Generally, there’s a lot you can customize when using Django, and that includes how to handle templates. If it feels cleaner to do it differently, do give it a go. :)

Rodrigo Vieira on Jan. 21, 2020

I could fix the “Template Not Found” error by just rerunning the ./ runserver command, without registering the templates directory in the TEMPLATES list in the file.

Brandy Wright on March 3, 2020

The tutorials and state of the files on screen video dont match. I believe it is because on one of the first tutorials in this course, I saw the .zip of the project.

So some stuff already works for me and I’m not getting the errors (errors are the point of this chapter).

The strange thing is parts that work when the file or text is NOT present.

For example: templates was already registered but the ‘DIRS’: was just []. The template still loads fine.

I added to it [os.path.join(BASE_DIR, 'projects/templates')], its still working. I’m curious about this…

Martin Breuss RP Team on March 5, 2020

Hi @Brandy Wright. The .zip file of the project already contains the finished code. To get the full experience of actively running into all the errors we’re covering here, I’d suggest to avoid that file and build the project from scratch. Just follow this tutorial step-by-step and you should be fine :)

Template DIRS

As for what you noticed with the DIRS list being empty in Django automatically registers template directories in registered apps, when they are called exactly that: templates. So there is no need to add these folder paths to You can define different directories as template directories, but then you will need to add them to the DIRS list.

I personally think it makes sense to be explicit and even record the template dirs of your apps in here.

Tomas Menito on March 9, 2020

Hi, great tutorial!

I have one quick question that is, instead of:

os.path.join(BASE_DIR, 'projects/templates')

Would it be better to use:

os.path.join(BASE_DIR, 'projects', 'templates')

To be more generic about os paths?


Martin Breuss RP Team on March 9, 2020

Hi @Thomas Menito and thanks for your comment! Yes, you’re absolutely right. With os.path.join it would be better to use:

os.path.join(BASE_DIR, 'projects', 'templates')

That makes it more general and avoids hard-coding the path separator, which might be different on different operating systems. Thanks for your 🦅👁 and for commenting here! 🙌

Andrew on May 26, 2020

Hello, In os.path.join(BASE_DIR, ‘projects/templates’) why don’t you have ‘projects/templatets/projects’) ? How does django know that it needs to go inside the second folder projects to get to the file index?

Martin Breuss RP Team on May 28, 2020

Hi @Andrew - great question :)

If you look a bit closer in the TEMPLATES settings dictionary right there in, you will find another option called APP_DIRS that is by default set to True:

        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        # more stuff

This setting ensures that Django automatically considers all files that are located inside of a folder called templates/ inside of each of your apps that you have registered in your project. You can experiment with setting it to False and notice how the templates are not found anymore.

eawongtheprogrammer on Aug. 30, 2020

I get an error:

NameError: name 'os' is not defined

I have have to insert import os at the beginning of

Is this normal?

Martin Breuss RP Team on Aug. 30, 2020

Hi @eawongtheprogrammer, the import for the os module should already be at the top of your file by default, if you used the way to create a Django project as described in this course.

You can check at this video at the timestamp ~4:50, where you can see that the import is necessary, but also should already be in your file.

Maybe you created your Django project in a different way, or maybe you accidentally deleted that import?

mmcdonell on Sept. 19, 2020

@eawrongtheprogrammer The import was never there. I ran into the same issue. I am now getting the following error after adding the import os:

NameError: name 'dirname' is not defined

Has something changed in the Django setup? Please adivse. Thanks.

Bartosz Zaczyński RP Team on Sept. 21, 2020

If you imported the os module directly, you must refer to dirname using its fully qualified name:

>>> os.path.dirname('/path/to/file.txt')

Alternatively, you could import the function itself:

>>> from os.path import dirname
>>> dirname('/path/to/file.txt')

Yes, Django switched from using a somewhat old os module in favor of the pathlib one, which we have a great tutorial about. (Martin uses Django 2.2.1, while the latest version of the framework is 3.1.1.)

mmcdonell on Sept. 23, 2020

To solve the error above I migrated to the updated version of django which is outlined in the django documentation . After I picked up from create an app to make sure I still had the same parameters that were displayed in the tutorial. The following BASE_DIR variable should be set to:

from pathlib import Path

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

the template DIR value should be:

'DIRS': [BASE_DIR / 'templates' ],

benirvingnz on Sept. 26, 2020

Thank you mmcdonell - very helpful!

Anung Ariwibowo on Jan. 3, 2021

Is it still necessary to declare templates in file when we use Django 3.1 and above?

Kyle R Conway on Jan. 5, 2021

Seems the new os.path.join is Path.joinpath(BASE_DIR, 'projects/templates'),

Bartosz Zaczyński RP Team on Jan. 7, 2021

@Kyle R Conway That’s right. Django recently switched to a somewhat more user-friendly pathlib module, which combines functionalities spread over a few places in the standard library. Joining paths has now a dedicated syntax, which takes advantage of the forward slash (/) operator:

>>> from pathlib import Path
>>> BASE_DIR = Path("/home/jdoe")
>>> BASE_DIR / "projects" / "templates"

Martin Breuss RP Team on Jan. 7, 2021

Hi everyone! Thanks for adding the updated info regarding Django 3.1 @mmcdonnell. Let me try to clarify the updates and what they mean.

Using pathlib

As @Bartosz mentioned further up, Django switched to using the pathlib module, which is a modern library to use for your file system interactions.

Django is nice to you, as usual, and gives instructions on how to work with the pathlib library right inside the code comments of

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

These few lines of code consists of the import for the Path class coming from the pathlib module, as well as the declaration of your BASE_DIR variable.

Now, that declaration might look a bit confusing at first, but all it does is reference back to the base directory from the current file that’s being executed (

If you consider a normal Django folder structure, like this one:

└── project
    ├── app
    │   ├──
    │   ├──
    │   ├── migrations
    │   ├──
    │   ├──
    │   └──
    └── project

You’re currently executing and you want to assign the variable BASE_DIR to the path of your project folder project.

That’s exactly what this line of code does:

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

Check the pathlib tutorial as your reference. In short:

  • Path(__file__) gets the path of the file that’s currently executed. This is in the management app called project in the schema above.
  • .resolve() turns that into an absolute path.
  • .parent steps one folder level up from the current file, so that you’re now in the project management app.
  • .parent steps up another folder level, so that you’re now in the project folder project, which is your project’s BASE_DIR.

From here on out you can define any path you need in relation to your base directory. With pathlib, this works by concatenating the name of your folder or file to an existing Path() object. This is what Django describes in the code comment above that line:

# Build paths inside the project like this: BASE_DIR / 'subdir'.

In order to define a specific directory as your templates directory, you’d therefore add its path to 'DIRS' in that way. For example:

        'DIRS': [BASE_PATH / 'my-templates'],
         # ... all the other code ...

This would declare a folder called 'my-templates' that lives at the base path of your project as a valid templates folder.

Note: The schema further up doesn’t include such a folder, but it would live in the base projects folder as a sibling to the management app projects and the app app.

As @Kyle mentions, you can also go deeper into any folder structure and add additional directories:

BASE_PATH / 'my-templates' / 'best-template-folder'

However, the path that @Kyle defined wouldn’t be necessary to put in there, because it follows the default Django structure.

So which template directories do you actually need to define?

Defining Template Directories

Generally, you don’t need to define template directories explicitly @Anung.

There’s a setting in the TEMPLATES variable in called 'APP_DIRS'. This is set to True by default. The setting defines whether Django looks for templates inside of your apps, assuming the default app structure that you learned about in this course.

As long as you leave the 'APP_DIRS' variable pointing to True, and stick with the default app folder structure of having a folder named templates/ inside of your app, then you don’t need to explicitly define a location in 'DIRS'.

You only need to define the location of your template folders if you don’t stick with the default app and folder structure, or if you set 'APP_DIRS' to False.

This works still the same as did in previous Django versions, and you can read more about it in the Configuration section of Django’s Template doc

Hope that helps to clarify what’s new in regards to defining paths in Django 3.1

Andy Pickett on March 11, 2021

Hi, great video as usual. Could I suggest that a little text note is added into the video that points to these comments for the changes relating the OS specifically?

It’s so well explained but its also easy to spend time assuming that you (the viewer) has made a mistake and searching through your code for the error.

Once again, thanks for all the hard work thats gone into these tutorials!

DoubleA on June 23, 2021

@Bartosz, @Martin,

Thank you guys for the valuable highlights in the comments. The pathlib part of this tutorial was somewhat confusing at first, but after watching the vid several times I figured out a typo in my views file and my templated started working! :) As a bonus I also did a part of the pathlib tutorial by Geir which btw was super clear and helpful!

Martin Breuss RP Team on June 24, 2021

Thanks for your feedback @Andy Pickett and @DoubleA :)

I’ve added a link to the discussion about pathlib here in the comments to the Description tab of this lesson. I hope that’ll make it easier for learners to find it.

prasadzende on Aug. 6, 2021

I am still having issues with the path , I have already emailed you the screenshot. I am not sure what is the problem ?

Martin Breuss RP Team on Aug. 6, 2021

Hi @prasadzende, it’ll be much easier to give you some help on this if you more closely describe what problem you are getting, what you’ve tried to solve it, and what your code configuration looks like.

From the screenshot you’ve shared, I can’t see any problem in your code. The development server seems to run fine.

As for your path in the DIRS setting in portfolio/, you don’t have to add the path in there, because you have the APP_DIRS entry set to True.

This means that Django will look into your app and find any templates that you have inside of a folder called templates/ in your app.

Keep going forward in the course, there are some lessons on debugging and explanations on how you need to set your template paths for everything to work as expected. Hope that helps!

prasadzende on Aug. 9, 2021

Hi Martin, I have solved the problem, thanks for the help.

ssharick8 on Nov. 7, 2021

I’ve created everything as thr video has, I’m pretty sure, and I’ve read through all the updated comments about the DIRS setting in the file. When I restart the server i get an error message of page not found and it says

Using the URLConfig defined in portfolio.urls, Django tried these url patterns in this order: 1. admin/ 2. projects/ The empty path didn’t match any of these.

But if I go into my browser address bar and add /projects to my local host, the proper html file appears.

I think I fixed it by adding the url pattern with the blank path that was created in the projects/ file back into the portfolio/ file. I’m still not sure if i did something wrong though.

Martin Breuss RP Team on Nov. 8, 2021

Hi @ssharick8 you didn’t do anything wrong, that’s the expected behavior. Like Django tells you:

Using the URLConfig defined in portfolio.urls, Django tried these url patterns in this order: 1. admin/ 2. projects/ The empty path didn’t match any of these.

That means Django looked whether the path your entered in your browser looked like this:

  1. localhost:8000/admin
  2. localhost:8000/projects

Since the path you entered was the empty path (localhost:8000/), Django couldn’t find any URL configuration that would let it know where to direct this request to.

Note: This is expected, because you didn’t set up URL routing for the empty path in this tutorial.

What you did was to set up a routing for the empty path to point to your portfolio view function. This is just a matter of taste as to where you want the content of your app to live.

In this tutorial, the original author decided to have all the portfolio projects at the /projects URL, and nothing at the empty path. That might make more sense if you have other parts to your app, e.g. a blog which you can then set up at /blog etc.

If you only have your projects, it’s a perfectly sensible choice to want to point the empty URL to your main view function that displays the list of portfolio projects. :)

Keep watching through the course, there will be more examples of handling URL configurations that might clarify a bit more what’s happening here. Hope this helps!

Catire22 on Feb. 9, 2022

I have read all of the comments and supporting Pathlib documentation and am still struggling. In, under templates, for DIRS what exactly should the syntax be if I have followed every other step?

Path.joinpath(BASE_DIR, ‘projects/templates’) ?

[BASE_PATH / ‘my-templates’] ?


Catire22 on Feb. 9, 2022

Ok so it is [BASE_DIR / ‘templates’ ],

Finally got it to work

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”),] } ]

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.

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.

simma99 on May 14, 2023

Hi. When I tried registering the templates folder in the 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)

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.

simma99 on May 19, 2023

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

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?

Pat Peters on Aug. 22, 2023

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

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 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.

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 runserver, which starts the development server

That’s all : )

Become a Member to join the conversation.