Search code examples
djangodjango-templatesdjango-admin

admin.display with mark_safe


Is there any chance I can put HTML in the <th> of change_list.html, other than going down the ugly road of overriding the admin_list template tags?

I want to style the text in the table head a little bit for viewing pleasure but it is quite tricky to access the table header in django.

I have something in mind like:

@admin.display(description = mark_safe("<b class='bg-danger'>status</b>"))
def get_status(self, obj):
    return obj.status

Solution

  • You can definitely embed HTML into the title/th for admin columns. Instead of using the admin.display decorator, try it like this:

    def get_status(self, obj):
        return obj.status
    get_status.short_description = mark_safe("<b class='bg-danger'>status</b>")
    

    You can see how it works in tthe source code: https://github.com/django/django/blob/3.2.16/django/contrib/admin/options.py#L860

    @staticmethod
    def _get_action_description(func, name):
        return getattr(func, 'short_description', capfirst(name.replace('_', ' ')))
    
    
    def _get_base_actions(self):
        """Return the list of actions, prior to any request-based filtering."""
        actions = []
        base_actions = (self.get_action(action) for action in self.actions or [])
        # get_action might have returned None, so filter any of those out.
        base_actions = [action for action in base_actions if action]
        base_action_names = {name for _, name, _ in base_actions}
    
        # Gather actions from the admin site first
        for (name, func) in self.admin_site.actions:
            if name in base_action_names:
                continue
                
            # RIGHT HERE IS WHERE IT CREATES THE TEXT FOR THE COLUMN TITLE/TH ELEMENT
            description = self._get_action_description(func, name)
            actions.append((func, name, description))
        # Add actions from this ModelAdmin.
        actions.extend(base_actions)
        return actions