Search code examples
pythondjangoadmin

Make link to foreign key object in admin screen


I have class like this which has the ForeignKey

class MyLog(SafeDeleteModel):
    user = models.ForeignKey(CustomUser,on_delete=models.CASCADE)

then I set user in the list_display of MyLog in admin page.

class MyLogAdmin(admin.ModelAdmin):
    list_display = ["id","user"]
class UserAdmin(admin.ModelAdmin):
    list_display = ["id","username"]

Now I want to make link in user of MyLogAdmin page to UserAdmin,

Is it possible?

I think some framework(such as php symfony) administrator system does this automatically.

However is it possible to do this by django admin?


Solution

  • This is, strangely enough, not a builtin feature. But we can effectively do this ourselves with:

    from django.utils.html import format_html
    
    
    class MyLogAdmin(admin.ModelAdmin):
        list_display = ['id', 'username_link']
    
        @admin.display(ordering='user__username', description='User')
        def username_link(self, obj):
            return format_html(
                '<a href="{}">{}</a>',
                reverse(
                    'admin:appname_customuser_change',
                    kwargs={'object_id': obj.user_id},
                ),
                obj.user,
            )

    with the appname the name of the app where you defined the CustomUser model (which is not per se the same as the MyLog model).


    Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


    Note: We can boost efficiency by fetching the details of related models in the same query in a ModelAdmin with the .list_select_related attribute [Django-doc]. In this specific case this thus looks like:

    class MyLogAdmin(admin.ModelAdmin):
        list_select_related = ['user']
        # …