Creating a “Hello, World” program is the traditional way to start a new programming project. In our case, we’ll learn how to build a simple Django application that simply says “Hello, World” on the homepage. Complete source code can be found on Github.

Create a virtual environment

First create and then activate a virtual environment called hello:

$ python3 -m venv ~/.virtualenvs/hello
$ source ~/.virtualenvs/hello/bin/activate

We will put our code on the Desktop in a directory called hello_world. To do so, open up a new command line console and type the following commands:

(hello) $ cd Desktop
(hello) ~/Desktop $ mkdir hello_world
(hello) ~/Desktop $ cd hello_world

This is important! ~/Desktop/hello_world is known as our root directory going forward. If we’re in a folder at the location ~/Desktop/hello_world/greetings I will refer to it as simply /greetings. All command-line instructions going forward are executed from our root directory.

Create a Django project

First install Django within our hello virtual environment:

(hello) $ pip install django

And then create a new Django project called helloworld_project. Make sure to include the period . at the end of the command below:

(hello) $ django-admin.py startproject helloworld_project .

If you use the tree command you can see what our Django project structure now looks like. (Note: Ubuntu users need to install tree with the following command sudo apt install tree.)

(hello) $ tree
.
├── helloworld_project
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

1 directory, 5 files

Let’s review what each new file does:

  • __init__.py can be safely ignored for now
  • settings.py controls all settings in our Django project; a few lines changed here will have a strong impact across our project
  • urls.py tells Django which pages to build in response to browser/url requests
  • wsgi.py stands for web server gateway interface, which helps Django serve our eventual web pages
  • manage.py takes various commands and feeds them into the correct part of Django. We will be using it extensively.

Start a server!

Django’s comes with a simple built-in local web server. At its core, a server simply registers URL requests from the browser and returns HTTP responses containing the data needed for a webpage. While the internal Django server is not robust enough for production use, it is more than adequate for local development purposes.

Use the runserver command to spin up Django’s server and confirm that everything is working so far:

(hello) $ python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).

You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

August 25, 2017 - 14:03:24
Django version 1.11.4, using settings 'helloworld_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Note: Ignore the warning about unapplied migrations for now; we are not using a database in this chapter.

If you visit http://127.0.0.1:8000/ you’ll now see a “Welcome to Django page” in light-blue.

Django welcome page

Start an App

A Django project contains one or more apps within it that all work together to power our web application. You can think of the project as the overall website while each app powers a specific functionality. For example, a real-world Django project might an app blog for powering an internal blog, a users app for user registration, and a payments app to accept online payments.

From the command-line console, quit our existing Django server by holding the Control and c keys at the same time, denoted as Control-c.

Next, create a new app called greetings with the following command:

(hello) $ python manage.py startapp greetings

Django creates an app structure within a new greetings folder. Using the tree command again we can see its layout:

(hello) $ tree
.
├── greetings
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── helloworld_project
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   └── settings.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

4 directories, 14 files

Let’s review what each app file does:

  • migrations/ keeps track of any changes to our models.py file so our database and models.py stay in sync
  • admin.py is a configuration file for the built-in Django Admin app
  • apps.py is a configuration file for the app itself
  • models.py is where we define our database models, which Django automatically translates into database tables
  • tests.py is for unit tests in our app
  • views.py is where we handle the request/response logic for our Web app

Settings

Now that we’ve created our first app, we need to tell Django to use it. Open the settings.py file and scroll down to INSTALLED_APPS:

# helloworld_project/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Django already comes with six built-in apps that provide standard web application functionality such as an admin, user authentication, sessions, static file management (images, JavaScript, CSS), and more.

We will explore each further but for now simply add our greetings app at the bottom:

# helloworld_project/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'greetings',
]

Views and URLConfs

Views and URLConfs work together to process browser requests and responses. When a user requests a specific page, for example /about/, the URLConf maps that request to the appropriate view function which then returns the correct data.

Let’s start with the view file for our app, which is located in the greetings/views.py file. In your text editor add the following Python code:

# greetings/views.py
from django.http import HttpResponse


def index(request):
    return HttpResponse("Hello, world!")

Let’s review what the code does here line-by-line:

  • first we import HttpResponse so we can return a response object to the user
  • next we define a function called index and pass it the argument request
  • then we hardcode our text, “Hello, world!”, to the response object

Views tell Django what to display to the user, but it does not say where on a website to display it. For that we need a URLConf, which uses Python regular expressions to map URLs (like /about/ or /contact/ etc) to specific views for, say, an about page or a contact page.

Create a new urls.py file within the greetings directory, which we can do with the touch command:

(hello) $ touch greetings/urls.py

And add the following Python code to our new file:

# greetings/urls.py
from django.conf.urls import url

from .views import index


urlpatterns = [
    url(r'^$', index),
]

Stepping through line-by-line we first import Django’s built-in url function which will be used to accept a list of url() instances lower down. Next we import our index view. And then we see the pattern for our first URLConf, which uses the url function, prefixed with r' which indicates a raw string expression in Python, and is linked to the view named index.

Don’t worry if this is all a little overwhelming at first. We’ll repeat this pattern of linking views and URLConfs again and again in our Django projects.

As a final step, we need to also update the URLConf for our entire project, which is located at helloworld_project/urls.py.

Why do we have two urls.py files? In a real-world Django project with many different apps, we want all the code for an app’s URLConfs to be in the app itself. Otherwise we would have one very long urls.py file at the project-level that contained the URLConfs for our entire project, which quickly becomes unwieldy.

Separating out app-specific URLConfs into a urls.py file in each app is the correct approach. This will make more sense in future chapters as we build more complicated websites.

Update the existing helloworld_project/urls.py file to look as follows:

# helloworld_project/urls.py
from django.conf.urls import include, url
from django.contrib import admin


urlpatterns = [
    url(r'^', include('greetings.urls')),
]

Hello, world!

We have all the code we need now. To confirm everything works as expected, restart our Django server and continue to ignore any warning about “unapplied migrations”:

(hello) $ python manage.py runserver
...

If you refresh the browser for http://127.0.0.1:8000/ it now displays the text “Hello, world!”

Hello world homepage

Conclusion

Congratulations! We built our first Django application! Along the way we learned about Django projects and apps, wrote our first view and URLConf, and used the internal web server.

Continue on to Chapter 3: A simple app and learn how to build a more complex Django application that uses templates and class-based views.




Sign up for the Django For Beginners newsletter for updates when new chapters are available and special discounts for the print edition of the book.