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

如何为Django ModelAdmin只读表单字段添加id属性以便JavaScript定位

方案1:动态修改表单widget属性(更推荐)

不通过readonly_fields配置只读状态,改为在表单初始化时动态给字段widget添加禁用/只读属性,Django会完整保留原生表单的id属性,和可编辑状态的id完全一致(格式为id_<字段名>),不需要修改JS定位逻辑。

针对select字段的实现代码如下:

from django import forms
from django.contrib import admin
from .models import YourModel # 替换为你自己的模型

class YourModelForm(forms.ModelForm):
    class Meta:
        model = YourModel
        fields = "__all__"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 存在实例主键时为更新场景,将字段设为只读
        if self.instance and self.instance.pk:
            # select原生不支持readonly属性,通过JS事件阻止选项变更
            self.fields["your_select_field"].widget.attrs.update({
                "readonly": "readonly",
                "onfocus": "this.defaultIndex = this.selectedIndex",
                "onchange": "this.selectedIndex = this.defaultIndex"
            })
            # 如果不需要提交该字段的值,可直接设为disabled,不需要加上面的事件
            # self.fields["your_select_field"].widget.disabled = True

class YourModelAdmin(admin.ModelAdmin):
    form = YourModelForm

方案2:自定义只读字段渲染函数

如果需要完全自定义只读状态的展示样式,可通过自定义字段渲染方法手动添加id属性:

from django.contrib import admin
from django.utils.html import format_html
from .models import YourModel

class YourModelAdmin(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        # 更新场景将原字段加入只读列表
        if obj:
            return ["your_select_field"] + list(self.readonly_fields)
        return self.readonly_fields

    # 自定义字段渲染逻辑
    def render_your_select_field(self, obj):
        # 手动生成和可编辑状态id一致的元素
        return format_html(
            '<span id="id_your_select_field">{}</span>',
            # 替换为你要展示的选项文本
            obj.get_your_select_field_display()
        )
    render_your_select_field.short_description = "你的select字段展示名"

    def get_fields(self, request, obj=None):
        fields = super().get_fields(request, obj)
        if obj:
            # 更新场景替换原字段为自定义渲染的字段
            fields = [f for f in fields if f != "your_select_field"] + ["render_your_select_field"]
        return fields

适用场景说明

  • 优先选方案1,代码改动量小,保留原生表单结构,不会出现表单提交取值异常的问题
  • 需要自定义只读状态的UI样式时再选方案2,注意手动保证自定义元素的id和原生可编辑状态的id一致即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:39:01