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

Django中如何用前一个HTML表单提交的数据预填充表单?

解决Django 2.2中跨表单预填充字段的问题

嘿,我完全懂你的需求——提交NewCashierForm后,自动把cashier_name和cashier_boxid的值带到NewPersonForm里,避免重复输入对吧?下面给你两种适配Django 2.2的可行方案,都是当前可用的:

方案一:通过URL查询参数传递数据

这种方法简单直接,适合不需要隐藏数据的场景:

1. 修改views.py中的addcashier视图

提交NewCashierForm成功后,重定向到addperson页面时,把需要传递的字段作为查询参数附在URL后面:

from django.urls import reverse
from django.http import QueryDict

def addcashier(request):
    if request.method == 'GET':
        form = NewCashierForm()
    else:
        form = NewCashierForm(request.POST)
        if form.is_valid():
            fs = form.save(commit=False)
            fs.user = request.user
            fs.save()
            # 构造要传递的参数并编码
            params = QueryDict(mutable=True)
            params['name'] = fs.cashier_name
            params['boxid'] = fs.cashier_boxid
            # 重定向到addperson并带上参数
            return redirect(f"{reverse('addperson')}?{params.urlencode()}")
    return render(request, 'main/addcashier.html', {'form':form})

2. 修改views.py中的addperson视图

在GET请求初始化表单时,读取URL中的查询参数,用initial参数预填充表单:

def addperson(request):
    if request.method == 'GET':
        # 从URL参数中获取值,没有的话为空字符串
        prefilled_name = request.GET.get('name', '')
        prefilled_boxid = request.GET.get('boxid', '')
        # 用initial初始化表单字段
        form = NewPersonForm(initial={
            'person_name': prefilled_name,
            'person_boxid': prefilled_boxid
        })
    else:
        form = NewPersonForm(request.POST)
        if form.is_valid():
            fs = form.save(commit=False)
            fs.user = request.user
            fs.save()
            return redirect('/addcashier')
    return render(request, 'main/addperson.html', {'form':form})

3. 给URL命名(可选但推荐)

在urls.py中给addperson路径加上name属性,方便后续用reverse调用:

from django.urls import path
from . import views

urlpatterns = [
    # 其他路径...
    path('addcashier/', views.addcashier, name='addcashier'),
    path('addperson/', views.addperson, name='addperson'),
]

方案二:通过Session存储数据

如果不想把字段值暴露在URL里,可以用Django的Session来临时存储数据:

1. 修改addcashier视图

保存Cashier对象后,把需要传递的数据存入Session:

def addcashier(request):
    if request.method == 'GET':
        form = NewCashierForm()
    else:
        form = NewCashierForm(request.POST)
        if form.is_valid():
            fs = form.save(commit=False)
            fs.user = request.user
            fs.save()
            # 存入Session临时存储
            request.session['cashier_prefill_data'] = {
                'name': fs.cashier_name,
                'boxid': fs.cashier_boxid
            }
            return redirect(reverse('addperson'))
    return render(request, 'main/addcashier.html', {'form':form})

2. 修改addperson视图

从Session中读取数据预填充表单,用完后记得删除Session中的数据(避免下次访问还带着旧数据):

def addperson(request):
    prefilled_data = {}
    # 检查Session中是否有预填充数据
    if 'cashier_prefill_data' in request.session:
        prefilled_data = request.session.pop('cashier_prefill_data')  # 取出并删除数据
    if request.method == 'GET':
        form = NewPersonForm(initial={
            'person_name': prefilled_data.get('name', ''),
            'person_boxid': prefilled_data.get('boxid', '')
        })
    else:
        form = NewPersonForm(request.POST)
        if form.is_valid():
            fs = form.save(commit=False)
            fs.user = request.user
            fs.save()
            return redirect('/addcashier')
    return render(request, 'main/addperson.html', {'form':form})

注意事项

  • 两种方案都完全兼容Django 2.2版本,不用担心过时问题;
  • 方案一中的QueryDict.urlencode()会自动处理特殊字符(比如空格、中文)的编码,避免URL乱码;
  • 方案二中的Session数据会在用户关闭浏览器后自动过期,也可以通过request.session.set_expiry()手动设置过期时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 06:36:49