Tutorial

How To Use PostgreSQL with your Django Application on Ubuntu 16.04

How To Use PostgreSQL with your Django Application on Ubuntu 16.04
Not using Ubuntu 16.04?Choose a different version or distribution.
Ubuntu 16.04

Introduction

Django is a flexible framework for quickly creating Python applications. By default, Django applications are configured to store data into a lightweight SQLite database file. While this works well under some loads, a more traditional DBMS can improve performance in production.

In this guide, we’ll demonstrate how to install and configure PostgreSQL to use with your Django applications. We will install the necessary software, create database credentials for our application, and then start and configure a new Django project to use this backend.

Prerequisites

To get started, you will need a clean Ubuntu 16.04 server instance with a non-root user set up. The non-root user must be configured with sudo privileges. Learn how to set this up by following our initial server setup guide.

When you are ready to continue, log in as your sudo user and read on.

Install the Components from the Ubuntu Repositories

Our first step will be install all of the pieces that we need from the repositories. We will install pip, the Python package manager, in order to install and manage our Python components. We will also install the database software and the associated libraries required to interact with them.

Python 2 and Python 3 require slightly different packages, so choose the commands below that match the Python version of your project.

If you are using Python 2, type:

  1. sudo apt-get update
  2. sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib

If, instead, you are using Python 3, type:

  1. sudo apt-get update
  2. sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib

With the installation out of the way, we can move on to create our database and database user.

Create a Database and Database User

By default, Postgres uses an authentication scheme called “peer authentication” for local connections. Basically, this means that if the user’s operating system username matches a valid Postgres username, that user can login with no further authentication.

During the Postgres installation, an operating system user named postgres was created to correspond to the postgres PostgreSQL administrative user. We need to use this user to perform administrative tasks. We can use sudo and pass in the username with the -u option.

Log into an interactive Postgres session by typing:

  1. sudo -u postgres psql

First, we will create a database for our Django project. Each project should have its own isolated database for security reasons. We will call our database myproject in this guide, but it’s always better to select something more descriptive:

  1. CREATE DATABASE myproject;

note

Remember to end all commands at an SQL prompt with a semicolon.

Next, we will create a database user which we will use to connect to and interact with the database. Set the password to something strong and secure:

  1. CREATE USER myprojectuser WITH PASSWORD 'password';

Afterwards, we’ll modify a few of the connection parameters for the user we just created. This will speed up database operations so that the correct values do not have to be queried and set each time a connection is established.

We are setting the default encoding to UTF-8, which Django expects. We are also setting the default transaction isolation scheme to “read committed”, which blocks reads from uncommitted transactions. Lastly, we are setting the timezone. By default, our Django projects will be set to use UTC. These are all recommendations from the Django project itself.

  1. ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
  2. ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
  3. ALTER ROLE myprojectuser SET timezone TO 'UTC';

Now, all we need to do is give our database user access rights to the database we created:

  1. GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;

Exit the SQL prompt to get back to the postgres user’s shell session:

  1. \q

Install Django within a Virtual Environment

Now that our database is set up, we can install Django. For better flexibility, we will install Django and all of its dependencies within a Python virtual environment. The virtualenv package allows you to create these environments easily.

If you are using Python 2, you can install the correct package by typing:

  1. sudo pip install virtualenv

If you are using Python 3, type:

  1. sudo pip3 install virtualenv

Make and move into a directory to hold your Django project:

  1. mkdir ~/myproject
  2. cd ~/myproject

We can create a virtual environment to store our Django project’s Python requirements by typing:

  1. virtualenv myprojectenv

This will install a local copy of Python and a local pip command into a directory called myprojectenv within your project directory.

Before we install applications within the virtual environment, we need to activate it. You can do so by typing:

  1. source myprojectenv/bin/activate

Your prompt will change to indicate that you are now operating within the virtual environment. It will look something like this (myprojectenv)user@host:~/myproject$.

Once your virtual environment is active, you can install Django with pip. We will also install the psycopg2 package that will allow us to use the database we configured:

Note

Regardless of which version of Python you are using, when the virtual environment is activated, you should use the pip command (not pip3).

  1. pip install django psycopg2

We can now start a Django project within our myproject directory. This will create a child directory of the same name to hold the code itself, and will create a management script within the current directory. Make sure to add the dot at the end of the command so that this is set up correctly:

  1. django-admin.py startproject myproject .

Configure the Django Database Settings

Now that we have a project, we need to configure it to use the database we created.

Open the main Django project settings file located within the child project directory:

  1. nano ~/myproject/myproject/settings.py

Towards the bottom of the file, you will see a DATABASES section that looks like this:

~/myproject/myproject/settings.py
. . .

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

. . .

This is currently configured to use SQLite as a database. We need to change this so that our PostgreSQL database is used instead.

First, change the engine so that it uses the postgresql_psycopg2 adaptor instead of the sqlite3 adaptor. For the NAME, use the name of your database (myproject in our example). We also need to add login credentials. We need the username, password, and host to connect to. We’ll add and leave blank the port option so that the default is selected:

~/myproject/myproject/settings.py
. . .

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'myproject',
        'USER': 'myprojectuser',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': '',
    }
}

. . .

While you are here, you may also need to adjust the ALLOWED_HOSTS directive. This defines a whitelist of addresses or domain names may be used to connect to the Django instance. Any incoming requests with a Host header that is not in this list will raise an exception. Django requires that you set this to prevent a certain class of security vulnerability.

In the square brackets, list the IP addresses or domain names that are associated with your Django server. Each item should be listed in quotations with entries separated by a comma. If you wish requests for an entire domain and any subdomains, prepend a period to the beginning of the entry. In the snippet below, there are a few commented out examples used to demonstrate:

~/myproject/myproject/settings.py
. . .
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . .]

When you are finished, save and close the file.

Migrate the Database and Test your Project

Now that the Django settings are configured, we can migrate our data structures to our database and test out the server.

We can begin by creating and applying migrations to our database. Since we don’t have any actual data yet, this will simply set up the initial database structure:

  1. cd ~/myproject
  2. python manage.py makemigrations
  3. python manage.py migrate

After creating the database structure, we can create an administrative account by typing:

  1. python manage.py createsuperuser

You will be asked to select a username, provide an email address, and choose and confirm a password for the account.

If you followed the initial server setup guide, you should have a UFW firewall in place. Before we can access the Django development server to test our database, we need open the port we will be using in our firewall.

Allow external connections to the port by typing:

  1. sudo ufw allow 8000

Once you have the port open, you can test that your database is performing correctly by starting up the Django development server:

  1. python manage.py runserver 0.0.0.0:8000

In your web browser, visit your server’s domain name or IP address followed by :8000 to reach default Django root page:

http://server_domain_or_IP:8000

You should see the default index page:

Django index

Append /admin to the end of the URL and you should be able to access the login screen to the admin interface:

Django admin login

Enter the username and password you just created using the createsuperuser command. You will then be taken to the admin interface:

Django admin interface

When you’re done investigating, you can stop the development server by hitting CTRL-C in your terminal window.

By accessing the admin interface, we have confirmed that our database has stored our user account information and that it can be appropriately accessed.

Conclusion

In this guide, we’ve demonstrated how to install and configure PostgreSQL as the backend database for a Django project. While SQLite can easily handle the load during development and light production use, most projects benefit from implementing a more full-featured DBMS.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
8 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

I found a small omission in your article:

$ virtualenv myprojectenv

When using python3, the command to initialize a venv should be:

$ virtualenv -p python3 myprojectenv

Also, this way of authorizing access to a database:

postgres=# GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;

seems intuitive, but inefficient - PostgreSQL documentation suggests assigning database ownership to a particular role (user) and then granting membership in that role to other roles (users) as needed. An easy shortcut to set it up can be, having created a role:

postgres=# CREATE DATABASE myproject OWNER myrole;

I hope my comment’s helpful :)

What happens when you use pip3 within a virtualenv instead of using pip?

Nicely written and organized tutorial, thanks for the efforts!

Unfortunately I have tried this and several other tutorials for using PostgreSQL, and none have been able to log in to the data base. All of the install is good, and then nothing will log in.

Thanks for tutorial

This comment has been deleted

    This comment has been deleted

      Great article, it helped me a lot in my project! Best regards! Miguel A. Gómez

      This comment has been deleted

        Try DigitalOcean for free

        Click below to sign up and get $200 of credit to try our products over 60 days!

        Sign up

        Join the Tech Talk
        Success! Thank you! Please check your email for further details.

        Please complete your information!

        Get our biweekly newsletter

        Sign up for Infrastructure as a Newsletter.

        Hollie's Hub for Good

        Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

        Become a contributor

        Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

        Welcome to the developer cloud

        DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

        Learn more
        DigitalOcean Cloud Control Panel