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

Django Admin如何实现字段有值时只读、无值时可编辑

问题原因

你当前的get_readonly_fields逻辑只判断了「是否是编辑已有对象」,没有判断字段本身是否已经存储值,所以只要是编辑页所有指定字段都会被设为只读,空字段也被锁死,不符合需求。

实现方案

核心逻辑:编辑已有对象时逐字段校验,仅当字段存在非空存储值时才加入只读列表,空值字段保留编辑权限。

修正后的admin.py代码

from django.contrib import admin
from . import models

class NameAdmin(admin.ModelAdmin):
    model = models.Name
    # 统一维护需要做只读控制的字段
    _readonly_control_fields = ("name", "id")

    def get_readonly_fields(self, request, obj=None):
        base_readonly = list(self.readonly_fields)
        # 新建对象场景,所有字段开放编辑
        if not obj:
            return tuple(base_readonly)
        
        # 编辑场景逐字段判断值
        for field in self._readonly_control_fields:
            val = getattr(obj, field, None)
            # 字段存在有效值就设为只读,空值跳过
            # 注意:BooleanField存False属于有效值,不是空
            if val not in (None, ""):
                base_readonly.append(field)
        
        return tuple(base_readonly)

模型层注意事项

你当前的模型代码有缩进错误,另外如果需要区分「未选择的空值」和「选择为否的False值」,需要给BooleanField加上空值配置,否则False会被判定为已存储值自动锁只读:

from django.db import models

class Name(models.Model):
    # 需要区分空值和False时,按如下配置,不需要的话保留原参数即可
    name = models.BooleanField(null=True, blank=True, default=None)
    # 注意:Django模型默认自带自增id主键,不建议手动覆盖id字段为其他类型,如果是业务字段请更换字段名
    id = models.BooleanField(null=True, blank=True, default=None)

    def __str__(self):
        return f"{self.name}"
效果对应
  • 新建对象页:所有控制字段可编辑,和截图1效果一致
  • 保存后有值的字段:自动转为只读状态,和截图2效果一致
  • 保存后仍为空的字段:保持可编辑状态,和截图3要求一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:36:17