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
相关产品推荐
相关产品推荐

