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

Unlock This Lesson

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

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Build Your Routes

In this lesson, you’re going to look at how to build routes. In the previous lesson, you tried a URL that doesn’t exist and got an error message that told you to check portfolio.url.

When you check that file, you can see all of the URL patterns that exist there. If you try to go to /projects, then you’ll see that it isn’t registered anywhere, so Django doesn’t know what to do with it. Fortunately, Django provides a lot of useful information in the comment at the top of that file.

00:00 Let’s get ready building our routes. So remember, we tried this /projects/ up here, we tried a URL that doesn’t yet exist, and we got this error message telling us, “Okay, okay. This is not working. Can’t find anything here, but why don’t you go ahead and check in portfolio.urls?

00:19 Maybe you should do something there.” So, over here in portfolio.urls, I’m taking a look and it tells me all the urlpatterns that currently exist is one path to /admin, and that directs forward to somewhere else.

00:36 But what I tried here was to go to /projects, and /projects isn’t registered anywhere here, so Django doesn’t know what to do with it.

00:46 But we can already see that it’s probably going to work in a similar way to how this 'admin/' works up there.

00:53 One thing that Django’s great at is—not only the error messages—but also just information that’s included when you start a new app or a new project. Really, all you need to know is written up here in this multiline comment.

01:08 We’re going to head straight to the last one that says Including another URLconf (URL configuration). And literally what I’m going to do here is just to read the instructions.

01:16 Django is telling me Import the include() function: from django.urls import include, path. We have from django.urls import path, so I’m just going to add this import include, path.

01:32 All right? PyCharm’s telling me I’m not using this yet, but we’ll get there, just give me a moment. Second, Add a URL to urlpatterns. So here, I’m going to make a new path().

01:45 You see, the structure is very similar to the one that we already have. We can even go ahead and just copy this. I’m going to take this, that’s what Django suggests me to do, is make a new one: path(), include().

02:02 Okay. But our app name is not blog. That’s just an example up here, so we’ll have to replace this here with our actual app name. I’m going to say 'projects/',

02:17 and that’s it. Now, include() is used, and we replicated exactly the suggestion that Django gave us up here. We made a new path() and it’s pointing to the URL projects/, and what we’re going to do next is we’re going to include projects.urls.

02:34 Okay, is that it? Let’s take a look! So, I’m over here again,

02:42 and I’m trying to call to this /projects/ URL, and I’m getting a new thing. So it’s telling us, refused to connect. Think of this as a new friend, right?

02:50 We’ve got a different error message. Again, this is a browser error message, not really a Django one, but same story all the way.

02:58 Heading back over here and finding out why is that happening, here it tells me ModuleNotFoundError: No module named 'projects.urls' exists. Remember?

03:11 This is one of our new friends. ModuleNotFoundError: No module named 'projects.urls'. It’s kind of self-explanatory, but it’s still a bit scary to see it sitting around like that, so let’s try to pick it apart.

03:27 Django seems to be looking for a module named projects.urls. That comes clearly from what we said here. We told it to include something that’s sitting inside of the projects app, and then it’s called .urls. Remember seeing that before, when it told us to look into portfolio.urls in the error message?

03:48 So, it seems that it was finding it there. So what we want to do is essentially just replicate this. We don’t currently have a urls file sitting in here.

03:58 That’s the module that it’s looking for. Okay. So what I’m going to do is inside of the projects app, I’m just going to create a module, a Python file, that I call urls.

04:13 I’m going to create a new Python file, call it urls.py. Okay, so there it is. Now, is that enough? Let’s try restarting our server.

04:35 Okay, so we get another error message, yippee! It’s telling us, If you see valid patterns in the file... blah, blah, blah, blah, blah,

04:50 ImproperlyConfigured... blah, blah, blah. django.core.exceptions..., blah, blah, blah. ...included URLconf 'module 'projects.urls'—okay, great!

04:58 So, as you see, it’s finding it, right? So what we created was good. Also, when you see a new friend, a new error message, that’s always a good sign because it tells you that what you did actually had an effect. So it’s telling us, “Okay, this ...does not appear to have any patterns in it.” Okay, so, The included URLconf, which is a success message telling us we managed to include the right thing, but currently, it ...does not appear to have any patterns in it.

05:28 If you see valid patterns in the file then the issue is probably caused by a circular import. We don’t really know what’s a circular import, but we can even see that Django gives us some tips here. However, that’s not the case for us right now.

05:39 There are no valid patterns in the file because this file, as of now, is completely empty. So, this is what applies. It doesn’t have any patterns in it. Let’s go ahead and fix that.

05:51 The simplest way of doing that is just heading over to this one. We know this one was working, so I’m just going to take what’s here and move it over to our new file.

06:05 Now, we’re not going to deal with this 'admin/', so I’m just going to get rid of it. And we don’t—actually, let me keep that. We don’t want to include, we don’t want to point forward to a different urls file—that’s what we did here—so I get rid of that.

06:22 And now maybe we can model something similar to what we were doing here.

06:29 What I want to say is if I get redirected to here, to this urls file, without anything else—you know, it’s just projects/ and then nothing else in the URL—then what I want to do is I want to point forward to somewhere else.

06:45 I want to point forward to where the logic happens in our Django app, which is going to be the views file.

06:55 Just cleaning up. I want to point into views and then project_list. That’s what I’m eventually going to want to create. Okay. So, here we have another error message that tells us Unresolved reference 'views'. That is because if we want to use the views inside of any app, we’re going to have to import it.

07:21 So I’ll say from projects import views.

07:27 Okay, so now this error’s gone, and PyCharm is already telling us something else, but let’s ignore this for now and restart our server…

07:42 to run into a new error! Ta-da! We’re going to deal with this error in the next video.

Pygator on Oct. 12, 2019

I get this mistake when rerunning the server after adding to the urlpatterns:

File “<frozen importlib._bootstrap>”, line 1006, in _gcd_import File “<frozen importlib._bootstrap>”, line 983, in _find_and_load File “<frozen importlib._bootstrap>”, line 965, in _find_and_load_unlocked ModuleNotFoundError: No module named ‘projects.urls’

Martin Breuss RP Team on Oct. 16, 2019

My guess from looking at your traceback is that you are somewhere referencing a urls.py file in a projects app folder that might not exist or be incorrectly linked.

Jon Lee on Jan. 13, 2020

I had a similar issue as Pygator when using ‘projects.urls’. The following seemed to solve the issue.

(in portfolio/urls.py)

from django.contrib import admin
from django.urls import include, path
from projects import urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('projects/', include(urls))
]

Martin Breuss RP Team on Jan. 14, 2020

Hello again, thanks for your comments. @Pygator, as a follow-up: did you make sure that the file projects/urls.py exists? You shouldn’t have created it yet at the beginning of this video, that’s why at ~3:11 I am handling the same error that you are talking about. This is expected if the file doesn’t exist yet, since Django can’t find the (non-existent) file.

@Jon Lee: In your case you already created the file, since you are able to import it in the way you showed. I would suggest, however, to stick with the way that Django proposes to handle the import:

path('projects/', include('projects.urls')

This avoids the necessity to import the file explicitly.

I assume that you were running into a different issue than @Pygator. Can you give it another go with the proposed way of linking to the app’s urls.py file that is mentioned in the video and in this post, and follow-up with the exact error message you are receiving, in case you run into one?

Please note that 'projects.urls' is indeed a string.

Jon Lee on Jan. 14, 2020

Hi Martin. I was running into another issue but that seems to have been solved now that you pointed out that ‘projects.urls’ is supposed to be a string. I didn’t wrap that section in quotes first time around. Thank you :)

Martin Breuss RP Team on Jan. 17, 2020

Great, glad to here you managed to fix it! 👏

Hi, Martin. When I tried to run the server, it gave me the error:

March 19, 2020 - 18:39:33
Django version 3.0.4, using settings 'portfolio.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Not Found: /
[19/Mar/2020 18:39:42] "GET / HTTP/1.1" 404 2033

However, I did implement

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('projects/', include('projects.urls')),
]

correctly as you did in porfolio/urls.py. Can you help me to fix this error? Thank you very much.

Martin Breuss RP Team on March 19, 2020

If you look closely at the error, it tells you what URL path it didn’t find:

Not Found: /

You did not create a urlpattern for the empty base URL (and neither did I when building out the project). So in short: your error is expected and if you navigate to one of the defined urlpatterns (/admin or /projects) you should see a page pop up :)

It works. Thanks Martin.

budescueftimie on March 26, 2020

after you import views you restart your server in the terminal, how do you do it? i cant write in my terminal. i have AttributeError: module ‘projects.views’ has no attribute ‘project_list’ and under its the blinking square but i cant write . how do you do that??

Martin Breuss RP Team on March 27, 2020

Hi @budescueftimie. Sometimes the development server gets stuck on an error. You can stop it by pressing Ctrl+D or Ctrl+C - or simply by closing your terminal window and opening up a new one.

Restart the server - and you should be good to go :)

budescueftimie on March 29, 2020

thank you, Ctrl+C works, i did not want to have to close and open a new terminal window everytime i get stuck in an error.

Joel Witherspoon on April 28, 2020

@budescueftimie If your keyboard has a function key, hold Ctrl+function and find the BREAK key and press it. The server should then release.

eddhyne on Aug. 11, 2020

While creating urls.py, I hit Save All by mistake and got all the friendly errors. They don’t look friendly to me. Please help.

PS G:\Django\Visual Studio Code Projects\django-portfolio> .\\.env\Scripts\activate
(.env) PS G:\Django\Visual Studio Code Projects\django-portfolio> python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "D:\Python38\lib\threading.py", line 932, in _bootstrap_inner
    self.run()
  File "D:\Python38\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 53, in wrapper
    fn(*args, **kwargs)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\management\commands\runserver.py", line 118, in inner_run
    self.check(display_num_errors=True)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\management\base.py", line 392, in check
    all_issues = checks.run_checks(
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\checks\registry.py", line 70, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\checks\urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\checks\urls.py", line 23, in check_resolver
    return check_method()
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\urls\resolvers.py", line 408, in check
    for pattern in self.url_patterns:
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\urls\resolvers.py", line 589, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\urls\resolvers.py", line 582, in urlconf_module
    return import_module(self.urlconf_name)
  File "D:\Python38\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "G:\Django\Visual Studio Code Projects\django-portfolio\portfolio\urls.py", line 21, in <module>
    path('projects/', include('projects.urls'))
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\urls\conf.py", line 34, in include
    urlconf_module = import_module(urlconf_module)
  File "D:\Python38\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'projects.urls'
Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    main()
  File "manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\management\__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\management\__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\management\base.py", line 330, in run_from_argv
    self.execute(*args, **cmd_options)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\management\commands\runserver.py", line 61, in execute
    super().execute(*args, **options)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\management\base.py", line 371, in execute
    output = self.handle(*args, **options)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\management\commands\runserver.py", line 96, in handle
    self.run(**options)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\core\management\commands\runserver.py", line 103, in run
    autoreload.run_with_reloader(self.inner_run, **options)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 613, in run_with_reloader
    start_django(reloader, main_func, *args, **kwargs)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 598, in start_django
    reloader.run(django_main_thread)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 313, in run
    self.run_loop()
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 319, in run_loop
    next(ticker)
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 359, in tick
    for filepath, mtime in self.snapshot_files():
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 375, in snapshot_files
    for file in self.watched_files():
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 274, in watched_files
    yield from iter_all_python_module_files()
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 105, in iter_all_python_module_files
    return iter_modules_and_files(modules, frozenset(_error_files))
  File "G:\Django\Visual Studio Code Projects\django-portfolio\.env\lib\site-packages\django\utils\autoreload.py", line 141, in iter_modules_and_files
    resolved_path = path.resolve(strict=True).absolute()
  File "D:\Python38\lib\pathlib.py", line 1177, in resolve
    s = self._flavour.resolve(self, strict=strict)
  File "D:\Python38\lib\pathlib.py", line 200, in resolve
    return self._ext_to_normal(_getfinalpathname(s))
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: '<frozen importlib._bootstrap>'
(.env) PS G:\Django\Visual Studio Code Projects\django-portfolio>

Martin Breuss RP Team on Aug. 12, 2020

Hello @eddhyne! But they really are friendly 🤗

While I don’t exactly know what’s happening here, I would look closer at this line:

ModuleNotFoundError: No module named ‘projects.urls’

This sounds to me like like the file you were working on, urls.py in your projects app might not have been saved correctly and the project overall is not aware of its existence.

What happens when you save your file and restart the development server?

Become a Member to join the conversation.