How to add a custom field in listview page ?

List of products

April 2020

To display fields of a model in listview page of the admin, we use the instruction :

list_display = ('user','refShop','title')

which tells django admin which fields to display. But what if we want to add a custom field such as a button, a link or a calculated field ?

You can find the source code in this repository

Like other posts, we will use the following models

# *coding: utf-8*
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User

class Shop(models.Model):
    user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
    name = models.TextField()
    email = models.CharField(max_length=200)
    address = models.CharField(max_length=1024,null=True, blank=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    def __str__(self):
        return u'%s' % (self.name)

class Product(models.Model):
    user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
    refShop = models.ForeignKey(Shop, db_index=True,on_delete=models.CASCADE)
    title = models.TextField(max_length=65)
    price = models.FloatField(default=0)
    withEndDate = models.BooleanField(default=False)
    endDate = models.DateField(blank=True,null=True)
    description = models.CharField(max_length=65, default='', null=True, blank=True)
    createdAt = models.DateTimeField(auto_now_add=True)
    updatedAt = models.DateTimeField(auto_now=True)
    available = models.BooleanField(default=True)
    def __str__(self):
        return u'%s - %s' % (self.refShop,self.title)

Let’s say we want to display a new column in the list to indicate that a product price is low. To do so, we can write the code:

class ProductAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ['user','refShop','title','price','withEndDate','endDate','description']}),
    ]
    list_display = ('user','refShop','title','has_low_price',)
    ordering = ('user','refShop',)

    def has_low_price(self, obj):
        return obj.price < 5

We define a has_low_price function and add it in our list_display method. As result, we will see the new column in the admin

Django admin custom field in listview

To display as a checkbox just add

has_low_price.boolean=True
Django admin custom boolean field

If you want to display a custom button, you can add your own html code

from django.utils.html import format_html
from django.utils.safestring import mark_safe

...

 @mark_safe
    def goToEditProduct(self, obj):
        return format_html(
            '<a class="button" href="/admin/backoffice/product/%s/change/?_changelist_filters=id__exact=%s" target="blank">Edit</a>&nbsp;' % (obj.pk,obj.pk))

    goToEditProduct.short_description = 'Edit'
    goToEditProduct.allow_tags = True
Django admin add custom button

In this example, we create an html button with a link to the change page of the product

Christophe Surbier