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

如何为Django TabularInline admin Formset创建自定义模板并显示超链接源?

解决Django Admin Inline中显示关联对象为文件超链接的问题

看起来你已经在尝试用自定义StackedInline模板来实现需求了,核心问题是如何从模板的field对象中拿到关联Source实例的source_name属性对吧?其实我们可以换个思路,直接获取到对应的模型实例,然后直接访问它的属性来生成超链接,下面给你两种可行的方案:

方案一:通过Admin自定义只读字段(更简单)

如果你的需求只是显示关联源的超链接,不需要在Inline里编辑这个字段,那完全不用写复杂的模板,直接在Admin的Inline类里定义一个自定义字段就行:

  1. 首先在admin.py里修改你的SourceInline:
from django.contrib import admin
from .models import Person, Source

class SourceInline(admin.StackedInline):
    model = Source
    extra = 0  # 不显示额外的空表单
    readonly_fields = ("source_file_link",)
    # 只显示我们自定义的字段,隐藏其他不需要的字段(如果需要保留其他编辑字段可以调整)
    fields = ("source_file_link",)

    def source_file_link(self, obj):
        # 只有已保存的对象才有pk和文件,新增时返回空
        if obj.pk:
            return f'<a href="{obj.file.url}">{obj.source_name}</a>'
        return ""
    
    # 允许渲染HTML标签
    source_file_link.allow_tags = True
    # 设置字段在Admin里显示的名称
    source_file_link.short_description = "关联源文件"

class PersonAdmin(admin.ModelAdmin):
    inlines = [SourceInline]

admin.site.register(Person, PersonAdmin)

这个方法的好处是不用修改模板,直接利用Django Admin的自定义字段功能就能生成超链接,非常简洁。

方案二:自定义Inline模板(适合需要保留编辑功能的场景)

如果你需要保留其他字段的编辑功能,只是把source_name对应的控件替换成超链接,那可以继续用你现有的自定义模板,调整模板代码来获取模型实例:

  1. 先确保你的SourceInline指定了自定义模板:
class SourceInline(admin.StackedInline):
    model = Source
    extra = 0
    template = "admin/source_inline.html"  # 替换成你的模板路径
  1. 修改你的自定义模板source_inline.html,重点是通过inline_admin_form.form.instance拿到关联的Source实例:
{% extends "admin/edit_inline/stacked.html" %}

{% block fieldset %}
  {% for inline_admin_form in inline_admin_formset %}
    {% with source=inline_admin_form.form.instance %}
      <div class="inline-group">
        {% if inline_admin_form.form.non_field_errors %}
          {{ inline_admin_form.form.non_field_errors }}
        {% endif %}
        {% for fieldset in inline_admin_form %}
          {% for line in fieldset %}
            {% for field in line %}
              {% if field.name == "source_name" %}
                {% if source.pk %}
                  <p><a href="{{ source.file.url }}">{{ source.source_name }}</a></p>
                {% else %}
                  {{ field.field }}  <!-- 新增对象时显示原控件 -->
                {% endif %}
              {% else %}
                {{ field.field }}  <!-- 其他字段正常显示 -->
              {% endif %}
            {% endfor %}
          {% endfor %}
        {% endfor %}
      </div>
    {% endwith %}
  {% endfor %}
{% endblock %}

关键知识点:

  • inline_admin_form是Django Admin传递给模板的Inline表单对象,inline_admin_form.form对应的是当前的ModelForm实例,inline_admin_form.form.instance就是关联的Source模型对象,通过它可以直接访问source_name、file.url等属性。
  • 判断source.pk是否存在是为了区分已保存的对象和新增的空对象,新增时还没有文件,所以还是显示原来的表单控件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:48:05