You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django admin中将多对多关联字段展示为可跳转超链接

Django Admin多对多字段渲染为可点击超链接方案

问题根因

返回列表格式的结果时,Django admin会将列表整体转为普通字符串输出,不会对列表内的单个安全HTML对象做渲染,因此只能看到文本无法生成可点击链接;返回单个format_html生成的安全字符串时可以被正常识别渲染。

直接修复方案

修改你的Admin类自定义字段方法,使用Django内置的format_html_join方法批量拼接多对多关联对象的链接,代码如下:

from django.contrib import admin
from django.urls import reverse
from django.utils.html import format_html_join

from .models import MyObject, RelatedObject

class MyAdmin(admin.ModelAdmin):
    # 注意单个元素的元组需要加逗号,否则会被识别为字符串触发报错
    list_display = ("rel",)

    def rel(self, obj):
        # 第一个参数为多个链接之间的分隔符,可根据需要修改为换行符<br>等其他内容
        return format_html_join(
            ", ",
            '<a href="{}">{}</a>',
            (
                (reverse("admin:<替换为你的APP名>_relatedobject_change", args=[item.id]), item.name)
                for item in obj.related.all()
            )
        )
    
    # 自定义列表页该列的表头名称
    rel.short_description = "关联对象"

    # 可选优化:添加prefetch_related避免多对多字段查询的N+1问题
    def get_queryset(self, request):
        return super().get_queryset(request).prefetch_related("related")

通用复用方案

如果需要在多个模型、多个多对多字段上复用该能力,可以封装通用生成方法,无需重复编写逻辑:

from django.utils.html import format_html_join
from django.urls import reverse

def generate_m2m_link_field(field_name, app_label, model_name, separator=", "):
    """
    生成多对多字段可点击链接的通用方法
    :param field_name: 多对多字段的字段名
    :param app_label: 关联模型所属的APP名称
    :param model_name: 关联模型的小写类名
    :param separator: 多个链接之间的分隔符
    """
    def _inner_field(self, obj):
        return format_html_join(
            separator,
            '<a href="{}">{}</a>',
            (
                (reverse(f"admin:{app_label}_{model_name}_change", args=[item.id]), str(item))
                for item in getattr(obj, field_name).all()
            )
        )
    _inner_field.short_description = field_name.replace("_", " ").title()
    return _inner_field

# 使用示例
class MyAdmin(admin.ModelAdmin):
    list_display = ("rel",)
    # 直接调用通用方法生成对应的字段处理逻辑
    rel = generate_m2m_link_field("related", "替换为你的APP名", "relatedobject")

注意事项

  • 代码中的<替换为你的APP名>需要替换为RelatedObject模型所属的Django应用的名称
  • 若不需要使用第三方linkify工具,以上原生方案完全可满足需求,无需额外依赖
  • 若需要关联对象之间换行展示,将分隔符从, 改为<br>即可

内容的提问来源于stack exchange,提问作者Shmuelt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 10:45:05