Background image

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)

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)

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.

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

Now the admin interface looks much better.

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)

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

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)

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

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

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)

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

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

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

You might also enjoy