Using PostgreSQL with Django – Complete Django Database Guide

PostgreSQL with Django

Django and PostgreSQL are one of the most popular combinations for building secure, scalable, and high-performance web applications. Django provides a powerful ORM and rapid development workflow, while PostgreSQL offers reliability, advanced SQL features, and excellent performance.

In this guide, you’ll learn how to use PostgreSQL with Django, covering database configuration, models, migrations, CRUD operations, performance optimization, and best practices for production deployments.

Why Use PostgreSQL with Django?

Although Django supports multiple databases, PostgreSQL is the recommended choice for production applications because it offers:

  • Full support for Django ORM features
  • Advanced indexing and query optimization
  • Native JSONB and full-text search support
  • Strong data integrity with ACID compliance

Many large-scale Django applications rely on PostgreSQL for stability and scalability.

Prerequisites

Before starting, make sure you have:

  • Python 3.10 or newer
  • Django 4.x or newer
  • PostgreSQL installed and running
  • Basic knowledge of Django and SQL

Installing Required Packages

First, install Django and the PostgreSQL adapter for Python:

pip install django psycopg2-binary

For production environments, you may use psycopg2 instead of psycopg2-binary.

Creating a Django Project

django-admin startproject myproject
cd myproject
django-admin startapp core

Add the app to INSTALLED_APPS in settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'core',
]

Configuring PostgreSQL in Django

Edit the DATABASES setting in settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'tutorialdb',
        'USER': 'postgres',
        'PASSWORD': 'yourpassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

Best Practice

Use environment variables to store sensitive credentials instead of hardcoding them.

Running Initial Migrations

python manage.py migrate

This command creates the default Django tables in PostgreSQL.

Creating Models in Django

Define a simple model in core/models.py:

from django.db import models

class Customer(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name

Applying Migrations

python manage.py makemigrations
python manage.py migrate

Django automatically generates SQL compatible with PostgreSQL.

Inserting Data Using Django ORM

from core.models import Customer

Customer.objects.create(
    name='John Doe',
    email='john@example.com'
)

Django handles SQL generation and execution behind the scenes.

Querying Data from PostgreSQL

customers = Customer.objects.all()

for customer in customers:
    print(customer.name, customer.email)

Common ORM Queries

  • filter() – retrieve specific records
  • get() – retrieve a single record
  • exclude() – exclude records

Updating Data

customer = Customer.objects.get(id=1)
customer.email = 'newemail@example.com'
customer.save()

Deleting Data

customer = Customer.objects.get(id=1)
customer.delete()

For production systems, consider implementing soft deletes.

Using PostgreSQL-Specific Features

JSONB Fields

from django.db import models

class Order(models.Model):
    metadata = models.JSONField()

PostgreSQL stores JSON efficiently using JSONB, making it ideal for semi-structured data.

Full-Text Search

from django.contrib.postgres.search import SearchVector

results = Customer.objects.annotate(
    search=SearchVector('name', 'email')
).filter(search='john')

Managing Transactions in Django

from django.db import transaction

with transaction.atomic():
    Customer.objects.create(name='Alice', email='alice@example.com')

Transactions ensure consistency across multiple database operations.

Performance Optimization Tips

  • Add indexes for frequently queried fields
  • Use select_related() and prefetch_related()
  • Avoid unnecessary ORM queries (N+1 problem)
  • Use PostgreSQL EXPLAIN ANALYZE for query tuning

PostgreSQL and Django Migrations Best Practices

  • Review migration files before applying them
  • Avoid large schema changes during peak traffic
  • Use zero-downtime migration strategies when possible

Using PostgreSQL with Django in Production

Recommended Settings

  • Enable persistent connections (CONN_MAX_AGE)
  • Use connection pooling (PgBouncer)
  • Enable SSL connections
  • Monitor slow queries and database size

Security Best Practices

  • Use strong database passwords
  • Apply least-privilege roles in PostgreSQL
  • Protect sensitive fields using encryption
  • Keep Django and PostgreSQL up to date

Common Use Cases

  • Content management systems
  • SaaS platforms
  • E-commerce applications
  • Data-driven dashboards
  • Enterprise web systems

Conclusion

Using PostgreSQL with Django gives you a powerful and reliable foundation for modern web applications. Django’s ORM combined with PostgreSQL’s advanced features allows developers to build scalable, secure, and maintainable systems efficiently.

By following best practices in configuration, migrations, performance tuning, and security, you can confidently deploy Django applications backed by PostgreSQL in production environments.

You may also like