Skip to content
First-class Postgres feature support for the Django ORM.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Adds first-class support for PostgreSQL features to the Django ORM.

Planned features include:

Obviously this is quite a large project, but I think it would provide a huge amount of value to Django developers.


PostgreSQL is an excellent data store, with a host of useful and efficiently-implemented features. Unfortunately these features are not exposed through Django's ORM, primarily because the framework has to support several SQL backends and so can only provide a set of features common to all of them.

The features made available here replace some of the following practices:

  • Manual denormalization on save() (such that model saves may result in three or more separate queries).
  • Sequences represented by a one-to-many, with an order integer field.
  • Complex types represented by JSON in a text field.


The following represents a whirlwind tour of potential features of the project:

from django.db import models
import django_postgres as pg

USStates = pg.Enum('states_of_the_usa', ['AL', ..., 'WY'])

class Address(pg.CompositeType):
    line1 = models.CharField(max_length=100)
    line2 = models.CharField(max_length=100, blank=True)
    city = models.CharField(max_length=100)
    zip_code = models.CharField(max_length=10)
    state = USStates()
    country = models.CharField(max_length=100)

class USPhoneNumber(pg.Domain):
    data_type = models.CharField(max_length=10)
    constraints = [
      r"VALUE ~ '^\d{3}-?\d{3}-?\d{4}$'"

class Customer(models.Model):
    name = models.CharField(max_length=100)
    shipping_address = Address()
    telephone_numbers = pg.Array(USPhoneNumber())
    is_preferred = models.BooleanField(default=False)

class PreferredCustomer(pg.View):
    projection = ['myapp.Customer.*']
    sql = """SELECT * FROM myapp_customer WHERE is_preferred = TRUE;"""

The SQL produced by this might look like:

CREATE TYPE states_of_the_usa AS ENUM ('AL', ..., 'WY');

CREATE TYPE myapp_address AS (
    line1 varchar(100),
    line2 varchar(100),
    city varchar(100),
    zip_code varchar(10),
    state states_of_the_usa,
    country varchar(100)

CREATE DOMAIN myapp_usphonenumber AS varchar(10)
    CHECK(VALUE ~ '^\d{3}-?\d{3}-?\d{4}$');

CREATE TABLE myapp_customer (
    shipping_address myapp_address,
    telephone_numbers myapp_usphonenumber[]

CREATE VIEW myapp_preferredcustomer AS
SELECT * FROM myapp_customer WHERE is_preferred = TRUE;

To create all your views, run python sync_pgviews

You can’t perform that action at this time.