[PYTHON] Link the list_display item in Django's Model Admin

What I wanted to do

In Django's ModelAdmin, I wanted to be able to link an item with list_display to the detail page for that item.

How to make list_display item link

For example, suppose the code before linking looks like this.

from django.contrib import admin

class FooModelAdmin(admin.ModelAdmin):
    list_display = ('foo','bar')

In the above code, if you want to link'foo'in list_display, do as follows.

from django.contrib import admin
from django.utils.safestring import mark_safe

class FooModelAdmin(admin.ModelAdmin):
    list_display = ('foo','bar')

    def foo_link(self, obj):
        return mark_safe(
            f'<a href="/foo/{obj.pk}/">{obj.foo}</a>'
        )

    foo_link.short_description = "foo"
    foo_link.admin_order_field = "foo"

By setting foo_link.short_description =" foo ", it is possible to display foo instead of foo_link. Also, by setting foo_link.admin_order_field =" foo ", you can sort by foo.

I think you can make a link like this. Please comment if you have any mistakes or better writing.

reference

https://stackoverflow.com/questions/3998786/change-list-display-link-in-django-admin https://stackoverflow.com/questions/47953705/how-do-i-use-allow-tags-in-django-2-0-admin/47953774

Note: Get stuck in mypy

Mypy throws an error for the following part of the code above.

    foo_link.short_description = "foo"
    foo_link.admin_order_field = "foo"
 error: "Callable[[FooModelAdmin, Any], str]" has no attribute "short_description"
 error: "Callable[[FooModelAdmin, Any], str]" has no attribute "admin_order_field"

This is an error like this.

solution

Upon examination, this problem seems to be a bug in mypy, and although it has been discussed quite a bit on github, it seems difficult to solve. At present, it seems that there is no choice but to add # type: ignore to the end of the sentence and let mypy ignore the type check.

from django.contrib import admin
from django.utils.safestring import mark_safe

class FooModelAdmin(admin.ModelAdmin):
    list_display = ('foo','bar')

    def foo_link(self, obj):
        return mark_safe(
            f'<a href="/foo/{obj.pk}/">{obj.foo}</a>'
        )

    foo_link.short_description = "foo"  # type: ignore
    foo_link.admin_order_field = "foo"  # type: ignore

Writing this way eliminates mypy errors.

Recommended Posts

Link the list_display item in Django's Model Admin
Make any key the primary key in Django's model
Customize the model page on Django's admin screen
What is on_delete used in django's model?
Benefits of using slugfield in Django's model
How to view images in Django's Admin
Search for yourself from methods in Django's model
Implement the autocomplete feature on Django's admin screen
Specify the lighting Model of SCN Material in Pythonista
Count the number of parameters in the deep learning model
How to use the exists clause in Django's queryset
How to use the model learned in Lobe in Python