Chapter 2: Hello World app
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
$ 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__.pycan be safely ignored for now
settings.pycontrols all settings in our Django project; a few lines changed here will have a strong impact across our project
urls.pytells Django which pages to build in response to browser/url requests
wsgi.pystands for web server gateway interface, which helps Django serve our eventual web pages
manage.pytakes 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.
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.
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
c keys at the same time, denoted as
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.pyfile so our database and
models.pystay in sync
admin.pyis a configuration file for the built-in Django Admin app
apps.pyis a configuration file for the app itself
models.pyis where we define our database models, which Django automatically translates into database tables
tests.pyis for unit tests in our app
views.pyis where we handle the request/response logic for our Web app
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
# helloworld_project/settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
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
indexand pass it the argument
- 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
/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
(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
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
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')), ]
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!”
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.