How do I add a custom column with a hyperlink in the django admin interface?

DjangoDjango Admin

Django Problem Overview


I have a django admin interface and in the model listing I want a custom column that will be a hyperlink using one of the fields values. Basically one of the models' fields is a url and i'd like the column to have that URL in a clickable hyperlink. This link will need to have additional URL prepended to it as its a relative path in the model field.

Django Solutions


Solution 1 - Django

Define a method in your ModelAdmin-class and set its allow_tags attribute to True. This will allow the method to return unescaped HTML for display in the column.

Then list it as an entry in the ModelAdmin.list_display attribute.

Example:

class YourModelAdmin(admin.ModelAdmin):
    list_display = ('my_url_field',)

    def my_url_field(self, obj):
        return '<a href="%s%s">%s</a>' % ('http://url-to-prepend.com/', obj.url_field, obj.url_field)
    my_url_field.allow_tags = True
    my_url_field.short_description = 'Column description'

See the documentation for ModelAdmin.list_display for more details.

Solution 2 - Django

Use the format_html utility. This will escape any html from parameters and mark the string as safe to use in templates. The allow_tags method attribute has been deprecated in Django 1.9.

from django.utils.html import format_html
from django.contrib import admin
from django.utils.translation import gettext_lazy as _

class MyModelAdmin(admin.ModelAdmin):
    list_display = ['show_url', ...]
    # ...

    @admin.display(description=_("Column title"))
    def show_url(self, obj):
        return format_html("<a href='http://pre.com{0}'>{0}</a>", obj.url)

Now your admin users are safe even in the case of:

url == '<script>eval(...);</script>'

See the documentation for more info.

Solution 3 - Django

I am using 'instance' instead of 'obj'. Seppo Erviälä's answer helped me the most as I'm using Django 3.0.1.

def get_facebook(self, instance):
    return format_html("<a target='_blank' href='{0}'>{0}</a>", instance.profile.facebook)
get_facebook.short_description = 'Facebook'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmikecView Question on Stackoverflow
Solution 1 - Djangouser257858View Answer on Stackoverflow
Solution 2 - DjangoSeppo ErviäläView Answer on Stackoverflow
Solution 3 - DjangoAlex WinklerView Answer on Stackoverflow