How to display multiple lines of text in django admin for Headers?

Similar questions that have already been asked are for data fields like in Here and Here
But how to split the header in multiple lines?
Considering a Django app with model and admin setup like this:

models.py

from django.db import models

class TaskItem(models.Model):
    group = models.ForeignKey(TaskGroup, on_delete=models.CASCADE)
    title = models.CharField(max_length=32, null=False, blank=False)
    description = models.CharField(max_length=45, null=False, blank=False)
    reward = models.IntegerField(default=1000, null=False, blank=False)

admin.py

class TaskItemAdmin(admin.ModelAdmin):
    list_display=['title', 'group', 'reward']
    list_filter=('group',)

How can I rename headers to Task Title, Task Group and Task Reward with line breaks?

In order to have custom names for your headers, you must use the Display decorator.

Like this:
(I recommend adding a prefix like _ to columns that you are customizing using a decorator in order to mitigate confusion with unmodified ones)

class TaskItemAdmin(admin.ModelAdmin):
    list_display=['_title', '_group', '_reward']
    list_filter=('group',)
    
    @admin.display(description='Task Title')
    def _title(self, obj):
        return obj.title
    
    @admin.display(description='Task Group')
    def _group(self, obj):
        return obj.group
    
    @admin.display(description='Task Reward')
    def _reward(self, obj):
        return obj.reward

This will customize headers appearance to the ones we just wrote, however if you try to use \n line breaks like @admin.display(description='Task\nReward') or HTML </br> tags like @admin.display(description='Task</br>Reward') in decorator section you might notice that none will work!
This happens as Django automatically escape HTML for some reason, that one of which is code injection.
That's why you might want to use format_html to partially enable HTML formatting in your code.

This is similar to str.format(), except that it is appropriate for building up HTML fragments.

So you can write something like this:
admin.py

class TaskItemAdmin(admin.ModelAdmin):
    list_display=['_title', '_group', '_reward']
    list_filter=('group',)
    
    @admin.display(description=format_html('{}</br>{}', 'Task', 'Title'))
    def _title(self, obj):
        return obj.title
    
    @admin.display(description=format_html('{}</br>{}', 'Task', 'Group'))
    def _group(self, obj):
        return obj.group
    
    @admin.display(description=format_html('{}</br>{}', 'Task', 'Reward'))
    def _reward(self, obj):
        return obj.reward

And the result would be something similar to:
Django admin panel showing the result

Вернуться на верх