首页 > 解决方案 > 在 django-admin 中使 HTML 自定义字段可排序

问题描述

我有一个非常简单的模型,只包含名称和序列号。我可以使用该序列号来询问 API 的状态,并且我想将结果显示为图标/HTML:

class ProductAdminForm(admin.ModelAdmin):
    class Meta:
        model = Product
        fields = ["get_status", "name",]

    def get_status(self, obj):
        status = get_status_from_API(obj)["status"]
        style = """style="height: 10px; width: 10px; border-radius: 50%; COLOR display: inline-block;" """
    
        if status == 2:
            new_style = style.replace("COLOR", "background-color: green;")
        elif status == 1:
            new_style = style.replace("COLOR", "background-color: red;")
        else:
            new_style = style.replace("COLOR", "background-color: grey;")
        return mark_safe(f"""<span class="dot" {new_style}></span>""")

如何使 get_status列可排序?

标签: djangodjango-admin

解决方案


您只能对数据库中的属性进行排序。

通常,不是实际数据库字段的 list_display 元素不能用于排序(因为 Django 在数据库级别进行所有排序)。

https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display

这意味着您无法在 API 中对对象的状态进行排序。但是,您可以通过设置对其他一些属性(例如序列号)进行排序admin_order_field

如果您真的想对状态进行排序,则需要以某种方式将此状态存储在数据库中。

一种解决方案是定期调用一个管理命令,该命令获取所有对象的状态并将结果存储在数据库中。

这使得根据对象的状态对对象进行排序(和过滤)成为可能。

将 API 结果存储在数据库中还有一个好处,就是在管理员中查看对象时不需要进行任何 API 调用。这在 API 发生故障/缓慢时特别有用。明显的缺点是结果可能会稍微过时,具体取决于调用更新命令的频率。


推荐阅读