Quickstart

Prerequisites

  • Python 3.11+

  • Django 4.2+

  • PostgreSQL (required; composite types are not available in SQLite or MySQL)

Your Django project must be configured to use a PostgreSQL database:

# settings.py
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "your_database",
        "USER": "your_user",
        "PASSWORD": "your_password",
        "HOST": "localhost",
        "PORT": "5432",
    }
}

Installation

pip install django-pint-field

Add to INSTALLED_APPS

INSTALLED_APPS = [
    # ...
    "django_pint_field",
    # ...
]

Run Migrations

python manage.py migrate django_pint_field

Caution

Failure to run django-pint-field migrations before running migrations for models using PintFields will result in errors. The migration creates a required composite type in your PostgreSQL database.

Previous versions of the package added three composite types to the database. The newest migration modifies the columns with these types to use a single composite type.

Basic Configuration

django-pint-field provides three settings you can add to your settings.py:

Setting

Type

Default

Description

DJANGO_PINT_FIELD_UNIT_REGISTER

UnitRegistry

pint.UnitRegistry(non_int_type=Decimal)

The unit registry to use throughout your project

DJANGO_PINT_FIELD_DECIMAL_PRECISION

int

0

Project-wide decimal precision. If > 0, sets Python’s decimal precision

DJANGO_PINT_FIELD_DEFAULT_FORMAT

str

“D”

Default format for displaying Quantity objects

See the configuration page for full details on each setting.

Quick Example

Define a model with a PintField:

# models.py
from django.db import models
from django_pint_field.models import DecimalPintField


class Product(models.Model):
    name = models.CharField(max_length=100)
    weight = DecimalPintField(
        default_unit="gram",
        unit_choices=[
            ("Gram", "gram"),
            ("Kilogram", "kilogram"),
            ("Pound", "pound"),
        ],
        blank=True,
        null=True,
        display_decimal_places=2,
        rounding_method="ROUND_HALF_UP",
    )

    def __str__(self):
        return f"{self.name} ({self.weight})"

Create instances and query the model:

from decimal import Decimal
from django_pint_field.units import ureg
from .models import Product

# Create a product
Product.objects.create(
    name="Flour",
    weight=ureg.Quantity(Decimal("500"), "gram"),
)

# Query products
heavy_products = Product.objects.filter(
    weight__gte=ureg.Quantity(
        Decimal("1"),
        "kilogram",
    )
)

Verifying Installation

  1. Check that the migration has been applied:

python manage.py showmigrations django_pint_field
  1. Verify the composite type exists in PostgreSQL. Open a database shell:

python manage.py dbshell

Then run:

\dT+ pint_field
  1. Test creating a model instance:

from decimal import Decimal
from django_pint_field.units import ureg
from myapp.models import Product

Product.objects.create(
    name="Test Product",
    weight=ureg.Quantity(Decimal("100"), "gram"),
)
  1. Verify unit conversion:

product = Product.objects.get(name="Test Product")
print(product.weight.quantity.to("kilogram"))  # Should show 0.1 kilogram
print(product.weight.kilogram)  # Alternate method. Should show 0.1 kilogram

Upgrading from Legacy Versions

Next Steps

Continue with the tutorial for a guided walkthrough, or jump to the how-to guides for specific tasks.