DEV Community

Juhana Jauhiainen
Juhana Jauhiainen

Posted on • Originally published at juhanajauhiainen.com

Customize Django admin with list_display property

One of the great "batteries included" features Django has, is the automatically generated admin panel. It provides a simple UI for creating, editing and deleting data defined with the Django ORM. In this article we are going to enable the admin user interface for a simple model and customize it from a simple list view to a more user friendly table like interface.

Lets say we have a simple model Item which has two fields nameand price.

class Item(models.Model):
    name = models.CharField(max_length=50)
    price = models.DecimalField(max_digits=5, decimal_places=2)
Enter fullscreen mode Exit fullscreen mode

Add the model to the admin page we only have to register it in the appsadmin.py file.

from django.contrib import admin
from .models import Item

admin.site.register(Item)
Enter fullscreen mode Exit fullscreen mode

Now when we run the app and open a browser to [http://localhost:8000/admin](http://localhost:8000/adminwe) and add a Itemwith the name Pizza using the admin panel.

Alt Text

By default the Django admin site displays model objects as a simple list with the string representation of the model object as title. Our model class doesn't provide a __str__ method so Django uses the models name as the title. We can fix this by adding a __str__method to our Itemmodel.


class Item(models.Model):
    name = models.CharField(max_length=50)
    price = models.DecimalField(max_digits=5, decimal_places=2)

    def __str__(self):
        return self.name
Enter fullscreen mode Exit fullscreen mode

Now the admin interface looks much better.

Alt Text

This is already nice but it would be easier to browse the existing Itemvalues if they were displayed as a table with values instead of a plain list.

We can customize the display by creating a custom admin model class and setting the value of list_displayproperty. Let's add a ItemAdminmodel to our admin.pyfile

from django.contrib import admin
from .models import Item

class ItemAdmin(admin.ModelAdmin):
    list_display = ("name", "price",)

admin.site.register(Item, ItemAdmin)
Enter fullscreen mode Exit fullscreen mode

Now we get a table like view of the existing Item objects.

Alt Text

ModelAdminalso allows us to create dynamic fields by declaring methods in ItemAdminand adding them to the list_displayproperty.

from django.contrib import admin
from .models import Item

from decimal import Decimal

class ItemAdmin(admin.ModelAdmin):
    list_display = ("name", "price", "vat")

    def vat(self, obj: Item) -> str:
        return f"{(obj.price * Decimal(0.05)):.2f}$"

admin.site.register(Item, ItemAdmin)
Enter fullscreen mode Exit fullscreen mode

Now we will get an extra field vat in our admin panel.

Alt Text

Another easy improvement to our admin view is allowing editing in the table view. Let's first add a boolean field is_available to our model.

from django.db import models

class Item(models.Model):
    name = models.CharField(max_length=50)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    is_available = models.BooleanField(default=True)

    def __str__(self):
        return self.name
Enter fullscreen mode Exit fullscreen mode

We can allow editing of a field by adding it to list_editabletuple property in it's model admin class.

from django.contrib import admin
from .models import Item

from decimal import Decimal

class ItemAdmin(admin.ModelAdmin):
    list_display = ("name", "price", "vat", "is_available")
    list_editable = ("is_available",)

    def vat(self, obj: Item) -> str:
        return f"{(obj.price * Decimal(0.05)):.2f}$"

admin.site.register(Item, ItemAdmin)
Enter fullscreen mode Exit fullscreen mode

Now we can set the is_availablevalue from the list view using a checkbox, without opening the detailed view.

Alt Text

For further reading I recommend going trough the Django documentation on ModelAdmin.

The example project with full source code is available at my github

Top comments (0)