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

如何按实例属性设置Django Admin部分内联条目为只读

Django Admin内联按单条实例设置只读状态实现方案

你遇到的问题本质是Django原生Inline的权限校验是内联全局级别的:TabularInline.has_change_permission()传入的obj是父模型(示例中的Author)实例,这个方法返回的结果会作用于所有内联条目,天然不支持单条子记录的权限判断。要实现按子实例特征区分读写状态,需要从表单渲染、后端校验两个层面实现,具体步骤如下(以2001年前出版的书籍内联条目只读为例):

1. 自定义内联表单集,逐行控制表单状态

内联的每一条记录对应InlineFormSet里的一个独立Form实例,重写表单集的_construct_form方法可以拿到当前行对应的子模型(Book)实例,在这里逐行设置字段的可编辑状态,同时加上后端校验防止前端绕过:

from django.forms.models import BaseInlineFormSet

class BookInlineFormSet(BaseInlineFormSet):
    def _construct_form(self, i, **kwargs):
        form = super()._construct_form(i, **kwargs)
        current_book = form.instance
        # 仅对已存在的、2001年之前出版的书籍做只读限制
        if current_book.pk and current_book.publish_year < 2001:
            # 将表单所有字段设为禁用,前端会自动渲染为不可编辑状态
            for field in form.fields.values():
                field.disabled = True
            # 给只读表单打标记,供后续校验使用
            form.readonly_flag = True
        return form

    def clean(self):
        super().clean()
        # 后端强制校验,禁止修改只读条目,防止篡改前端参数提交
        for form in self.forms:
            if getattr(form, "readonly_flag", False) and form.has_changed():
                form.add_error(None, "2001年及以前出版的书籍记录不允许修改")
            # 如需禁止删除只读条目,可加以下逻辑
            if getattr(form, "readonly_flag", False) and form.cleaned_data.get("DELETE"):
                form.add_error("DELETE", "2001年及以前出版的书籍记录不允许删除")

2. 绑定表单集到内联类

将自定义的表单集配置到TabularInline上,即可实现按条目的只读控制:

from django.contrib import admin
from .models import Author, Book

class BookInline(admin.TabularInline):
    model = Book
    formset = BookInlineFormSet  # 绑定上面自定义的表单集
    extra = 1  # 控制新增空白条目的数量
    fields = ("title", "publish_year", "publisher")

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ("name",)
    inlines = [BookInline]

补充说明

  • 上述逻辑对TabularInline和StackedInline通用,Django 2.0+到4.2+版本均测试可用
  • 不要仅依赖前端的disabled属性做限制,必须保留后端clean校验逻辑,避免恶意构造请求篡改数据
  • 新增的、尚未保存到数据库的内联条目(无主键值)默认保持可编辑状态,如果需要对新增条目做特殊限制,可以在_construct_form里通过current_book.pk is None判断单独处理

内容的提问来源于stack exchange,提问作者Justin H.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.22 16:15:01