Skip to main content

django-admin-display

PyPI GitHub Workflow Status (master) Coveralls github branch PyPI - Python Version PyPI - License

Simplifies the use of function attributes (eg. short_description) for the django admin and makes mypy happy :)

Note: Django 3.2+ has @display and @action decorators built-in.

Requirements

  • Python 3.10 or newer
  • Django 5.2 or newer

The support range follows the upstream support policies: Django 5.2 is the oldest release still receiving security support and Python 3.10 is the oldest Python release supported by Django 5.2. See What Python version can I use with Django? and the Python version status.

Python Django
3.10 5.2
3.11 5.2
3.12 5.2, 6.0, 6.1
3.13 5.2, 6.0, 6.1
3.14 5.2, 6.0, 6.1

Installation

pip install django-admin-display

Usage

If you want to change the behaviour of how Django displays a read-only value in the admin interface, you can add some special attributes to the corresponding method. Supported values are

short_description
Customize the column’s title of the callable.

empty_value_display
Show this value instead, if the value of a field is None, an empty string, or an iterable without elements.

admin_order_field
Indicate that the value is represented by a certain database field. This can also be a query expression.

boolean
Display a pretty “on” or “off” icon if the method returns a boolean.

The following example shows, how you normally apply these attributes to an AdminModel or a Model method.

class Company(models.Model):
    ...

    def owner(self) -> bool:
        return self.owner.last_name

    owner.short_description = "Company owner"
    owner.admin_order_field = 'owner__last_name'

This module replaces the way of defining these attributes by providing a handy decorator.

from django_admin_display import display


class Company(models.Model):
    ...

    @display(
        description="Company owner",
        ordering='owner__last_name',
    )
    def owner(self) -> bool:
        return self.owner.last_name

The display decorator mirrors the parameter names of Django's built-in django.contrib.admin.display and is fully typed, so mypy keeps the decorated method's signature.

display sets
boolean boolean
ordering admin_order_field
description short_description
empty_value empty_value_display

The older admin_display decorator remains available for backwards compatibility. It accepts the original parameter names (boolean, admin_order_field, short_description, empty_value_display) and delegates to display.

Why?

There are mainly two reasons why this module exists.

Usage with @property

It is quite common that a calculated model property is displayed in the admin interface:

class Company(models.Model):
    ...

    @property
    def created_on(self) -> datetime.date:
        return self.created_at.date()

In order to add special attributes, you have to create a protected method, attach the attributes and wrap that method using property():

class Company(models.Model):
    ...

    def _created_on(self) -> datetime.date:
        return self.created_at.date()

    _created_on.short_description = "Created on"
    created_on = property(_created_on)

This is quite cumbersome, hard to read and most people don't know that this is even possible. To overcome these downsides you can achieve the same result using the @display decorator:

from django_admin_display import display


class Company(models.Model):
    ...

    @property
    @display(
        description="Created on",
    )
    def created_on(self) -> datetime.date:
        return self.created_at.date()

mypy

If you are using mypy, you have probably stumbled over an error similar to this one

"Callable[[Any, Any], Any]" has no attribute "short_description"

A common solution is to ignore the type checking by adding # type: ignore to the end of the line:

class CompanyAdmin(admin.ModelAdmin):
    ...

    def created_on(self, company: models.Company) -> datetime.date:
        return company.created_at.date()

    created_on.short_description = "Created on"  # type: ignore

The issue is already known and heavily discussed on github.

This decorator solves the issue by internally using # type: ignore and providing a well-defined signature for setting the attributes. It is not an optimal solution but works well until the issue has been resolved.

Development

This project uses uv for packaging and dependency management, ruff for linting and formatting, mypy for static type checking and pytest for tests.

Clone this repository and run

uv sync

to create a virtual environment containing all dependencies. Afterwards, you can run the test suite using

uv run pytest

The test suite drives a real Django admin project (see tests/) end to end: it logs in through the admin login form, renders the changelist, follows the sortable column headers and submits the add form.

To lint and format the code, run

uv run ruff check --fix .
uv run ruff format .

and to type check the package and tests

uv run mypy django_admin_display tests

pre-commit hooks are configured to run ruff before every commit:

uvx pre-commit install

This repository follows the Conventional Commits style.

Metadata

Release files for django-admin-display 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-admin-display 2.0.0
File Size Uploaded
django_admin_display-2.0.0.tar.gz 275.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-admin-display 2.0.0
File Interpreter ABI Platform
django_admin_display-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 281.0 kB

Release files / django_admin_display-2.0.0.tar.gz

Download URL django_admin_display-2.0.0.tar.gz
Size 275.2 kB
Tags Source
SHA-256 checksum
How to use checksums
6776f1345883915657a76d3eea13f0a95a81aa23a882e335f7d157af533e84cf
BLAKE2b-256 checksum
How to use checksums
2e511d9b508ff11d4457e65128dbec5cd1e75cfbe660d476249c18e2c99700b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / django_admin_display-2.0.0-py3-none-any.whl

Download URL django_admin_display-2.0.0-py3-none-any.whl
Size 5.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a10774737794dab95c990085f06ffc44afc6dbdcb26487d0ba2aa3bb8163d0a6
BLAKE2b-256 checksum
How to use checksums
a217702f5107f28534e39fb4d6f08d20455cc19f8750797336caaaa75dded2a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page