In this module we’re going to start putting together the various components that make up a Django application.
You’ll remember from Module 1 that Django uses the Model– Template–View (MTV) design pattern. To refresh your memory the process flow of MTV is as follows:
- The Model retrieves data from the database, which is requested by the;
- View, which applies any business logic and formatting to the model data and then sends the packaged and formatted data to the;
- Template, which then renders the data with any display logic necessary.
It doesn’t matter what order you put these components together when building a Django application.
Some people like to start by building all the models so they can see how the data structure looks, others prefer to build the visual layout first so they start with templates. Others will just start at whatever point seems logical for the project.
Being pragmatic to the bone I am usually in the last group. I try not to get fixated on what someone else thinks is the right or the wrong way to do things and just try to find the simplest and quickest way to achieve the result I want. I also like to work incrementally starting small getting the flow right and building on that to create the complete application, which is exactly the process we’re going to follow in this course.
Before we get to creating our first view we need to dig a little deeper into our Django project’s structure to better understand how the pieces fit together and then create the key component that makes the MTV pattern work—a Django application.
Django Project Structure
When you ran the startproject command in module 2 Django created several files and folders for you. These files and folders form the basic framework of a Django project. While the defaults created by the startproject command are not the only way to structure a Django project, it is by far the most common, so Let’s take a closer look at what Django has created for us so far. Open your project folder.
Let’s examine these files and folders in more detail:
env_mfdwfolder is where the files for your virtual environment are stored. There are lots of interesting goodies in here for advanced users, but as a beginner it’s best you leave everything inside this folder alone.
- The outer
mfdw_sitefolder is merely a container for your project. While the
startprojectcommand created the folder, Django doesn’t care about the folder name, so you can rename it to something meaningful to you.
- Inside the outer
mfdw_sitefolder are two files:
db.sqlite3. The database created when you ran the migrate command; and
manage.py. A command-line utility for executing Django commands from within your project.
- The inner
mfdw_sitefolder is your Django project. The
init.pyfile within this folder tells Python that this directory is a Python package.
asgi.pyenables ASGI compatible web servers to serve your project. This file is only used in deployment.
settings.pycontains the setting for your project.
urls.pycontains project-level URL declarations. By default, this contains a single URL pattern for the admin.
wsgi.pyenables WSGI compatible web servers to serve your project. This file is only used in deployment.
Most of these files don’t have a lot in them right now so we won’t be going through them in detail. But I do want to draw your attention to one file we are going to be revisiting many times while developing our Django project—the Django settings file.
settings.py file contains the configuration information for your Django project. When you ran startproject, Django added a list of common settings with default values to this file. There are dozens of settings available—core settings for database configuration, caching, email, file uploads and globalization, as well as a range of additional settings for authentication, messaging, sessions and static file handling.
Now that you have a better understanding of how a Django project is structured it’s time to move on and create your first Django application.
You might have noticed that there’s no real program code in your project so far—you have a settings file with configuration information, an almost empty URLs file and a command-line utility that launches a website that doesn’t really do anything.
This is because to create a functioning Django website, you need to create Django applications.
A Django application (or app for short) is where the work is done. Good design practice says that each Django app should do one thing—a blog, or article directory or music collection, for example.
A Django project is the collection of apps and configuration settings that make up a Django website.
Apps are one of Django’s killer features. Not only do they allow you to add functionality to a Django project without interfering with other parts of the website, but apps are designed to be portable, so you can use one app in multiple projects.
Rename the site folder
Before creating our first app, we need to make one important change to the project folders—rename the outer
A very common complaint I get from programmers just starting out with Django is how confusing it is to know which folder they should be working in when there are two folders with the same name.
As I said earlier in the module, Django doesn’t care what you name this folder—so let’s go ahead and break thirteen years of Django tutorial convention and rename the folder! In this case, we’re going to rename it to “mfdw_root”.
Creating the Pages App
Now we’ve cleared up any potential confusion, let’s go ahead and create our first Django app.
If you’ve ever used a content management system, or visited websites with multiple sources of information, you may have noticed that they often break their content up into broad categories—pages for site-related information, articles for news and periodic information and maybe even blogs where contributors post shorter, more personal content.
We won’t be going into such detail in this introductory course, but we’ll create a simple but practical website—one that displays a few pages of information about our fictitious company Meandco Web Design.
Since we want to display pages of information, let’s call our app something practical—pages.
Return to the virtual environment command prompt (make sure you are in the
mfdw_root directory) and enter:
(env_mfdw) ...\mfdw_root> python manage.py startapp pages
Your project directory should now look like this:
\mfdw_project \mfdw_root \mfdw_site \pages db.sqlite3 manage.py
Notice that your new
pages app is in the same directory as
manage.py, not inside the
mfdw_site folder. It’s important that you get this right, otherwise you will get “no module named ‘pages'” errors when trying to run code later in the course.
If you do make a mistake, it’s very easy to fix. Delete the
\pages folder out of the
\mfdw_site folder, open the command window in
\mfdw_root and run the
startapp utility again.
Once you’ve created your app, you need to tell Django to install it into your project. This is easy to do—inside your
settings.py file is a list named
INSTALLED_APPS. This list contains all the apps that are installed in your Django project. Django comes with a few apps pre-installed, we just need to add your new
pages app to the list:
INSTALLED_APPS = [ 'pages.apps.PagesConfig', 'django.contrib.admin', # more apps ]
Note that Inside every app, Django creates a file,
apps.py, that contains a configuration class named after your app. In this case, the class is named
PagesConfig. To register our app with Django, we need to point to the
PagesConfig class—which is exactly what we are doing in line 2 or our modified
If you were wondering,
PagesConfig by default contains a single configuration option: the name of the app—in our case “pages”.
Django App Structure
Now let’s have a closer look at the structure of our new pages app:
migrationsfolder is where Django stores migrations, or changes to your database. There’s nothing in here you need to worry about.
__init__.pytells Python that your pages app is a package.
admin.pyis where you register your models with the Django admin application.
apps.pyis a configuration file common to all Django apps.
models.pyis where the models for your app are located.
tests.pycontains test procedures that will be run when testing your app.
views.pyis where the views for your app are located.
You’ll notice that most of these files are either empty, or only have a couple of lines of code in them. This is because Django’s startproject and startapp utilities only create the bare minimum framework for a Django website.
Remember, Django adds no boilerplate, no cruft and no unnecessary code, leaving you with a simple, clean framework that you can build on to create exactly what you want.
As I mentioned earlier you can create all the files and folders for a Django website manually. As your programming career progresses, you’ll find there are many ways to structure a Django project. However you’re better off starting with the structure created by startproject and startapp because this is the most common way to build a Django project.
Your First View
To create our first view, we need to modify the
views.py file in our pages app. Don’t forget to pause the video and copy the code either from the screen or from your transcript for this lesson.
Let’s examine this code closely:
- Line 1. Imports the
rendermethod. This is added to the file automatically by startapp.
render()is used when rendering templates, which we’ll cover in module 6.
- Line 2. We add an import for
HTTP, the communication protocol used by all web browsers, uses request and response objects to pass data to and from your app and the browser. We need a response object to be able to pass view information back to the browser.
- And in Lines 4 and 5 we have our view code. This is an example of a function-based view. It takes a request from your web browser and returns a response. In this case, it’s a simple line of text formatted as an HTML heading.
Note that the name of the view isn’t important. I’m just following the historical convention that the root page (home page) of a website is named
Configuring the URLs
If you started the development server now, you would notice that it still displays the welcome page. This is because for Django to use your new view, you need to tell Django that this is the view you want displayed when someone navigates to the site root (home page). We do this by configuring our URLs.
In Django, the
path() function is used to configure URLs. In its basic form, the
path() function has a very simple syntax:
Here’s A practical example of the basic path() function:
In this example, a request to
/mypage would be routed to the
myview function in the application’s
views.py file. Don’t worry if this is a bit confusing right now, it’ll make a lot more sense once you have written a couple of views. The
path() function also takes an optional
name parameter and any number of additional keyword arguments passed as a Python dictionary. The
path() function statements are kept in a special file called
startproject created our website, it created a
urls.py file in our site folder. This is a good place for site-wide navigation, but is rarely a good place to put URLs relating to individual applications. Not only is having all our URLs in the one file more complex and less portable, but can lead to strange behavior if two applications use a view with the same name.
To solve this problem, we create a new
urls.py file for each application. If you are wondering why
startapp didn’t create the file for us, not all apps have public views. A utility program that does background tasks, for example, would not need a
urls.py file. Remember, Django doesn’t assume anything, so it lets you decide whether your app needs its own
First, we need to create a new
urls.py file in our
Go ahead and create the file then pause this video and enter the code off the screen or from your transcript.
Let’s look at this code closer:
- Line 1. Imports the
path()function. This import is necessary for the URL dispatcher to work and is common to all
- Line 2. Imports the local
views.pyfile. The dot operator (“.”) in this case is shorthand for the current package, so this is saying “import all views from the pages app”.
- Line 4. Lists the URL patterns registered for this app. For readability, the list is broken into multiple lines, with one URL pattern per line.
- Line 5. Is the actual URL dispatcher:
- The empty quotes match an empty string. It will also match the forward slash as Django removes the slash from the end of all URLs.
views.index. Points to the index view in the pages app. Remember that we imported the index view in Line 2.
Now we need to make a change to our site
urls.py file so that it includes the URLs from our pages app. Once again you can pause the video and copy the changes from the screen or copy them from your transcript.
We have made a couple of important changes to the file:
- Line 17. We have added the
include()function to our imports.
- Line 21. We have added a new URL dispatcher. In this case, the dispatcher is simply including the
urls.pyfile from the
pagesapp. The empty string will match everything after the domain name. NOTE: This pattern must be the last entry in the list. The reason for this will become apparent in a later module.
If you now run the development server, you should see a plain, but functioning home page.
So, What Just Happened?
To better understand how Django works, let’s build on the generic example from module 1 with a concrete example of what Django did to display our home page:
- First, our browser sent a message to the Django development server requesting it return content located at the root URL. As Django removes the slash from the end of all URLs the pattern to match will be an empty string.
- Django then looked for a URL pattern that matched the request, by starting at the site level
- Django checks the first pattern in our site level
urls.pywhich doesn’t match and then moves on to the second line in which the empty string matches.
- The matching pattern includes the
pagesapp. Basically this include says “go look in the
pagesapp for a pattern that matches”.
- Once in the pages
urls.py, the empty string matches again, but this time the request is sent to the
indexview then renders our simple HTML message to a
HttpResponsethat is sent to the browser.
- Finally, the browser renders the response and we see our page heading.
Every Django application follows this same basic process each time it receives a request from the browser.
So that’s it for your 1st Django app. In the next module, we’ll create a Django model to contain the content for each of our site pages. We’ll also visit Django’s admin app for the first time and create some pages and content for our site.