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

Django实现仅含值的特定行字段只读,现有代码导致空行无法编辑

问题原因

你当前的代码里,get_readonly_fields方法接收的obj是父模型的实例,不是Inline中每一行的Calendar对象。只要进入编辑页面(父对象存在),所有行的registrations和calendar字段都会被设为只读,自然包括新增的空行。

解决方案

要实现「仅让有值的特定行字段只读」,需要针对Inline的每一行实例单独判断,推荐用自定义Form来实现:

步骤1:定义自定义Inline Form

from django import forms
from .models import Calendar

class CalendarInlineForm(forms.ModelForm):
    class Meta:
        model = Calendar
        fields = "__all__"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 仅对已存在的记录(非空行)进行判断
        if self.instance.pk:
            # 检查目标字段是否有值,按需调整判断逻辑
            has_registrations = bool(self.instance.registrations)
            has_calendar = bool(self.instance.calendar)
            
            if has_registrations:
                self.fields["registrations"].widget.attrs["readonly"] = True
            if has_calendar:
                self.fields["calendar"].widget.attrs["readonly"] = True

    # 可选:后端验证,防止前端调试修改提交
    def clean_registrations(self):
        if self.instance.pk and bool(self.instance.registrations):
            return self.instance.registrations
        return self.cleaned_data["registrations"]

    def clean_calendar(self):
        if self.instance.pk and bool(self.instance.calendar):
            return self.instance.calendar
        return self.cleaned_data["calendar"]

步骤2:在Inline中使用该Form

class CalendarInline(admin.TabularInline):
    model = models.Calendar
    form = CalendarInlineForm
说明
  • 自定义Form的__init__方法中,通过self.instance.pk判断是否为已存在的记录(空行的instance没有pk),再检查字段是否有值,针对性设置只读。
  • 可选的clean_xxx方法是为了严格控制数据:即使用户通过浏览器调试工具修改了前端只读状态,后端也会返回原有值,确保数据不被篡改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:24:32