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

Django ModelForm如何实现Laravel old()式的表单旧值保留?

在Django ModelForm中实现Laravel old('field_name') 式的表单值保留功能

在Laravel中我们通过old('field_name')显示用户此前输入的表单值,现在需要在Django的ModelForm中实现相同效果——表单验证失败时自动保留用户之前的输入内容,无需重新填写。

你当前的代码

表单代码:

class AddMenuForm(forms.ModelForm):
    def __init__(self,*args,**kwargs):
        x=super(AddMenuForm, self).__init__(*args, **kwargs)
        return x
    class Meta:
        model=Menu
        fields="__all__"

        widgets = {
            'title': forms.TextInput(attrs={
                'class': 'form-control',
                'id':'inputname',
                'placeholder':  "نام آیتم"
            }),
            'url': forms.TextInput(attrs={
                'class': 'form-control',
                'id': 'inputurl',
                'placeholder': " mr-keshi.ir /"
            }),

视图代码:

class addMenu(FormView):
    template_name = "Menu/addMenu.html"
    success_url = reverse_lazy('Menu')
    form_class = AddMenuForm

    def get_context_data(self, **kwargs):
        if (self.kwargs['menu'] not in Menu.placeMenu):
            # Todo: send error message
            pass
        data = super(addMenu, self).get_context_data(**kwargs)
        data['places'] = Menu.placeMenu
        data['place'] = self.kwargs['menu']
        return data

    def form_valid(self, form):
        print("form valid")
        menu = self.kwargs.get('menu')
        if (menu in Menu.placeMenu):
            form.save()
        else:
            pass

            # Todo: send error message
        # Todo:send success message
        return True
    def form_invalid(self, form):
        print("form is not valid")
        return super(addMenu, self).form_invalid(form)

解决方案

Django的FormView和ModelForm本身就自带表单值保留功能,只需修正几个关键问题即可:

  1. 修正视图的form_valid方法
    你当前的form_valid直接返回True,破坏了FormView的正常流程,导致验证成功后的重定向逻辑异常,同时可能影响验证失败时的表单状态传递。修改为调用父类的form_valid方法:
def form_valid(self, form):
    print("form valid")
    menu = self.kwargs.get('menu')
    if menu in Menu.placeMenu:
        form.save()
        # 可在此添加成功提示,比如使用Django messages框架
        # messages.success(self.request, '菜单添加成功')
    else:
        # 添加错误提示
        # messages.error(self.request, '无效的菜单位置')
        pass
    return super().form_valid(form)
  1. 模板中正确渲染表单字段
    必须通过表单对象渲染字段,而不是手动编写原生<input>标签,这样Django才会自动填充验证失败前的用户输入值。示例模板代码:
<form method="post">
    {% csrf_token %}
    <!-- 渲染title字段,自动保留旧值 -->
    {{ form.title }}
    <!-- 渲染url字段 -->
    {{ form.url }}
    <!-- 其他字段同理 -->
    <button type="submit">提交</button>
</form>

你已经在表单的widgets中定义了字段的HTML属性,渲染时会自动应用这些属性,同时填充旧值。

  1. 简化表单的__init__方法
    当前的__init__方法仅调用父类构造,无额外逻辑,可直接删除以简化代码:
class AddMenuForm(forms.ModelForm):
    class Meta:
        model = Menu
        fields = "__all__"
        widgets = {
            'title': forms.TextInput(attrs={
                'class': 'form-control',
                'id':'inputname',
                'placeholder':  "نام آیتم"
            }),
            'url': forms.TextInput(attrs={
                'class': 'form-control',
                'id': 'inputurl',
                'placeholder': " mr-keshi.ir /"
            }),
        }

关键原理

当表单验证失败时,FormView的form_invalid方法会将带有用户输入数据和错误信息的表单实例传递给模板,只要你通过{{ form.field_name }}的方式渲染字段,Django就会自动填充用户之前输入的值,实现和Laravelold('field_name')相同的效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 11:23:15