Getting started with Django

Django is a high-level Python web framework that helps you build web applications. You know, sites like Pinterest, Disqus, NASA, Eventbrite and others.

However, before you can even dream of reaching the sophistication of those sites you must learn the fundamentals.

In this post, I will show you the best way that I've found to get started on any new Django project.

Prerequisites

If you've been following along and have read my previous posts then feel free to skip ahead.

Otherwise, please make sure you have Git, Python and PostgreSQL set up on your machine. Read the following to learn how I do it:

  1. Getting started with Git on Ubuntu
  2. Getting started with Python on Ubuntu
  3. Getting started with PostgreSQL on Ubuntu

Let's begin

For our running example, I'll assume we're building a blog application called yaba. Yaba stands for Yet Another Blog Application.

$ mkdir yaba && cd yaba
$ pyvenv venv
$ . venv/bin/activate
(venv) $

Within the virtual environment you'll need to upgrade pip and setuptools and install the Django package.

(venv) $ pip install -U pip setuptools
(venv) $ pip install Django

Then, use django-admin to start a new Django project called yaba.

(venv) $ mkdir src && django-admin startproject yaba src

Here's what we have so far:

yaba (you're in here)  
├── src
│   ├── manage.py
│   └── yaba
│       ├── __init__.py
│       ├── settings.py
│       ├── urls.py
│       └── wsgi.py
└── venv
    ├── ...

And, here's a quick summary on the purpose of each file shown above.

  • yaba/__init__.py: It tells Python that blog/blog is a package directory. Read here to learn more.
  • yaba/settings.py: A Python module with module-level variables that contains all the configuration of your Django installation. Read here to learn more.
  • yaba/urls.py: A Python module informally called a URLconf (URL configuration). It contains a module-level variable called urlpatterns that represents a mapping between URL patterns (simple regular expressions) to Python functions (your views). Read here to learn more.
  • yaba/wsgi.py: It contains the WSGI configuration for your project. WSGI stands for Web Server Gateway Interface and it is a specification that describes how a web server communicates with web applications.
  • src/manage.py: It's Django's command-line utility for performing administrative tasks. Read here to learn more.

Now let's migrate the database, start the development server and navigate to http://127.0.0.1:8000/ to view the "Welcome to Django" page.

(venv) $ python src/manage.py migrate
(venv) $ python src/manage.py runserver

If you've done everything correctly you should see the following page:

Welcome to Django

If you don't see that page then hit me up in the comments below and I'd help you troubleshoot the problem.

Once everything is working fine, stop the development server by pressing Ctrl-C and we can begin to prepare for the first commit.

First commit

The work we did above created some files and directories that we don't want to track in our git repository. Git allows us to explicitly state what we don't want tracked by specifying them in a file called .gitignore. Learn more here.

Go ahead and create a .gitignore file in your project's root directory and edit it to contain:

__pycache__/  
venv/  
*.sqlite3

Next add a README.rst and a LICENSE.txt. I like to use http://choosealicense.com/ to help me choose an open source license.

(venv) $ touch README.rst LICENSE.txt

Edit README.rst to contain:

yaba - Yet Another Blog Application  
===================================

A blog web application built with `Django <https://www.djangoproject.com/>`_.

License  
-------

MIT  

Edit LICENSE.txt to contain:

MIT License

Copyright (c) [year] [fullname]

Permission is hereby granted, free of charge, to any person obtaining a copy  
of this software and associated documentation files (the "Software"), to deal  
in the Software without restriction, including without limitation the rights  
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
copies of the Software, and to permit persons to whom the Software is  
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all  
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  
SOFTWARE.  

Don't forget to replace [year] and [fullname].

N.B. I got the license text here.

Finally, freeze the requirements and make your first commit.

(venv) $ pip freeze > requirements.txt
(venv) $ git init
(venv) $ git add .
(venv) $ git commit -m "Initial commit"

Here's the commit of what we did so far, Initial commit.

Use PostgreSQL instead of SQLite

Django uses SQLite by default. Since we'd eventually be using PostgreSQL in production it's recommended that we use it in development as well. You can learn more about the idea, dev/prod parity, here.

Step 1

Install the psycopg2 package. psycopg is a PostgreSQL adapter for Python. It is what allows us to connect and do things with PostgreSQL through Python.

(venv) $ pip install psycopg2

See here for more help on installing the adapter.

Step 2

Create the PostgreSQL database.

$ createdb yaba

See here to learn more about createdb.

Step 3

Configure Django to connect to the PostgreSQL database. Open yaba/settings.py and edit the DATABASES setting.

Currently it looks as follows:

DATABASES = {  
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

If you have PostgreSQL configured to use peer authentication over a Unix domain socket,

# Contents of /etc/postgresql/9.6/main/pg_hba.conf
# ...
# "local" is for Unix domain socket connections only
local    all    all    peer  

then by omitting the 'HOST' key in DATABASES['default'], psycopg2 connects using a Unix domain socket. And, the following setting would suffice:

DATABASES = {  
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'yaba',
    }
}

If on the other hand you have PostgreSQL configured to use a password-based authentication method over TCP/IP,

# Contents of /etc/postgresql/9.6/main/pg_hba.conf
# ...
# IPv4 local connections:
host    all    all    127.0.0.1/32    md5  
# IPv6 local connections:
host    all    all    ::1/128         md5  

then by specifying the 'HOST' key in DATABASES['default'], psycopg2 connects using TCP/IP. And, the following setting would be needed instead:

DATABASES = {  
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'yaba',
        'USER': '[user]',
        'PASSWORD': '[password]',
        'HOST': 'localhost',
        'PORT': '5432'
    }
}

N.B. You need to supply the [user] and [password] values that are specific to your setup.

For your information, I usually take the first approach.

Step 4

Migrate the database, run the development server and navigate to http://127.0.0.1:8000/ to view the "Welcome to Django" page as before.

(venv) $ python src/manage.py migrate
(venv) $ python src/manage.py runserver

Step 5

Remove the old SQLite database file.

(venv) $ rm src/db.sqlite3

Step 6

Update requirements.txt and commit the changes.

(venv) $ pip freeze > requirements.txt
(venv) $ git add .
(venv) $ git commit -m "Switch to PostgreSQL"

Here's the commit for this part, Switch to PostgreSQL.

Conclusion

Congratulations on reaching this far. Today you learned the following:

  1. How to work within a virtual environment.
  2. How to install Django.
  3. How to use Git to track your changes.
  4. How to use PostgreSQL in your development environment.

You're now in a great place to continue building out the blog application.

Until next time, happy hacking :).

References

P.S. Meet me in the comments below and let me know if this was helpful to you or not. Did I do something you didn't fully understand? I'm here to help so just let me know.

P.S.S. Reach out to me if you want to learn how to host your project on GitHub.