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

Django表单设置只读字段无效,求可行解决方案

解决Django表单code字段只读失效的问题

先排查你可能踩的核心坑:如果表单的__init__方法没调用父类构造函数,设置的只读属性根本不会生效。下面给你几种靠谱的实现方案:

方法1:在表单__init__中正确配置(推荐)

确保你正确覆盖__init__并调用super(),这样设置的属性才会生效:

class NewCustomerForm(forms.ModelForm):
    class Meta:
        model = Customer
        fields = ['name', 'code', 'note']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 前端层面限制用户编辑
        self.fields['code'].widget.attrs['readonly'] = True
        # 也可用disabled,注意disabled字段不会随表单提交,适合你这种视图生成值的场景
        # self.fields['code'].disabled = True

方法2:重定义表单字段时指定只读属性

直接在表单里重写code字段,给widget添加只读属性:

class NewCustomerForm(forms.ModelForm):
    code = forms.IntegerField(
        widget=forms.NumberInput(attrs={'readonly': 'readonly'}),
        required=False  # 因为值由视图生成,无需用户输入
    )

    class Meta:
        model = Customer
        fields = ['name', 'code', 'note']

关键注意事项

  • 前端readonly只是视觉限制,懂技术的用户可修改HTML绕过,所以后端必须做校验:保存实例时,不要用表单提交的code值,直接用你视图生成的数值覆盖。
  • 如果用disabled=True,该字段不会随表单提交,后端直接用提前生成的code赋值给实例即可,完全不用担心被篡改。

示例视图逻辑参考:

def add_customer(request):
    # 生成code的业务逻辑,这里仅做示例
    generated_code = 1001  

    if request.method == 'POST':
        form = NewCustomerForm(request.POST)
        if form.is_valid():
            customer = form.save(commit=False)
            customer.code = generated_code  # 手动赋值视图生成的code
            customer.save()
            # 后续跳转或返回成功提示
    else:
        # 初始化表单时传入生成好的code
        form = NewCustomerForm(initial={'code': generated_code})
    
    return render(request, 'your_template.html', {'form': form})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 01:06:25