在Django同1个页面中的多表单处理详解
发布时间 - 2026-01-10 22:48:09 点击率:次快速上手Django实现项目

近期公司在做1个海淘的项目,APP为pylot。由于时间比较赶,加上隔壁那哥们不在,只能自己挑大梁了。结果,当项目做出来之后,被领导狠狠的批了一顿,说怎么用django写,你能解决Django的内存问题吗,你能解决并发的问题吗?Django那么重。
然后我只好回答说,正是因为它重,所以人家拿来写大型项目。虽然这里不是为了上面这2个问题的,而是来说下如何快速开发原型的问题。
对于Django这样基于模型的Web框架,实话说真的解决了很多繁琐的工作。由于它1个模型对应1张表,因此只要很短暂的时间就把原型给弄完了。实际上,我用Django主要是不用被页面浪费我的时间,这样我就可以专心写API那方面了。
结果,公司这个项目除了自己可以看到外,还要实现1个B端的需求,而我此时的后台功能已经完成了,这可以如何是好。而区别在于只能让注册的用户只能看到属于它自己的订单,而其他不变。
于是上官方文档看了下表单的教程,看到1个ModelForm的玩意,通过它可以将后台的表单直接渲染出来,而后在ModelForm类中通过instance关键字可以将对应模型直接渲染出来,这样花了1个星期的时间就把API、B端和公司的后台完成了,效率还算比较高。
下面说下如何通过Django快速实现项目:
- 实际上分解问题很关键,把问题按等级划分有助于加快开发速度
- 把不怎么会写的代码先跳过,使用繁琐的方式先写上去,后面再用其内建的方式来替换
- 不要紧张,一定要保持淡定,不然你会发现你完全写不出代码
- 不要看官方文档,因为写的啰嗦又难找到重点
- 带着问题在网上搜索答案,如果某个方式不行就换种思路去做,比如要实现1个多对多的关系的HTML组件,直接找第3方插件而不是看文档实现
相信如何能做到以上几点,才能把django的效率发挥出来。下面来看看本文的详细介绍吧。
Django同1个页面中的多表单处理
关于在同1个页面多个表单提交的问题,实际上是项目中遇到的1个小问题。关于这个问题,主要有2个需要解决的问题:
- 多个表单的渲染问题
- 多个表单提交时外键的处理问题
下面我们分别进行说明。
当时在建模的时候使用了类似如下的方式:
from django.db import models
class Store(models.Model):
name = models.CharField('名称', max_length=20)
first = models.FloatField('首重')
additional = models.FloatField('次重')
img = models.ImageField('图片', upload_to='store/1')
class Depot(models.Model):
s_name = models.ForeignKey(Store, verbose_name='仓库')
src = models.CharField('始发地', max_length=20)
dest = models.CharField('目的地', max_length=20)
days = models.PositiveSmallIntegerField('需要的天数')
class Address(models.Model):
s_name = models.ForeignKey(Store, verbose_name='仓库')
country = models.CharField('国家', max_length=20)
state = models.CharField('省份', max_length=10)
city = models.CharField('城市', max_length=10)
description = models.TextField('描述', blank=True)
在这里,1个仓库的数据主要由3个表组成,分别为它的一些基础信息,可以配送的范围、天数及其他一些附加信息组成。然后其页面如下所示:
多表单渲染
而公司的需求就是我们要在商户端上让客户在创建仓库时填写上述的内容,由于我比较懒,而公司给出的时间也不是很充裕,于是直接使用ModelForm来实现,而不需要一一的创建表单了。换句话说,我们要将多个模型表在同1个页面中渲染出来,对于这样的问题,主要有4种解决的方案:
- 在1个form组件中使用多个模型表单类
- 使用django提供的modelform_factory来解决
- 使用第3方插件django-betterforms或django-multipleformwizard这样的插件
- 使用元类,然后继承BaseForm进行表单的重写。
这里我们使用第1种解决方案来实现多个表单渲染的问题。
这里我们在forms模块下新建3个模型表单类:
from django.forms import ModelForm from models import Store, Address, Depot class StoreForm(ModelForm): class Meta: model = Store fields = '__all__' class AddressForm(ModelForm): class Meta: model = Address exclude = ['s_name'] class DepotForm(ModelForm): class Meta: model = Depot exclude = ['s_name']
然后在视图中引入这3个表单:
from django.shortcuts import render_to_response, HttpResponseRedirect
from django.template import RequestContext
from forms import StoreForm, AddressForm, DepotForm
def store_add(req):
if req.method == 'POST':
...
else:
sf = StoreForm()
af = AddressForm()
df = DepotForm()
return render_to_response('store_add.html', {
'sf': sf, 'af': af, 'df': df,
}, context_instance=RequestContext(req))
默认情况下,我们先将对应的表单渲染出来先。在这里我们往模板中输出了多个变量,然后在模板中手动进行如下的处理:
<form action="" method='post' enctype='multipart/form-data'>
{% csrf_token %}
{{ sf.as_p }}
{{ df.as_p }}
{{ af.as_p }}
<input type="submit" value = "添加" />
</form>
在这里,我们在1个表单中输出多个表单,其页面如下所示:
可以看到其效果与后台的页面相差不是很大,只是没有对应的样式而已。
多表单提交外键处理
接着我们需要处理多个表单提交时的处理问题。
def store_add(req):
if req.method == 'POST':
sf = StoreForm(req.POST, req.FILES)
af = AddressForm(req.POST)
df = DepotForm(req.POST)
if sf.is_valid() and af.is_valid() and df.is_valid():
sf.save()
df.save()
af.save()
return HttpResponseRedirect('store')
...
在这里我们直接对这3个表单进行保存,结果出现了这样1个错误。
NOT NULL constraint failed: app_depot.s_name_id
由于我们使用了1个外键进行了约束,而使用上述的方式会导致数据表中的s_name_id的字段数值为NULL,从而导致了错误。而上述的方式时直接就提交给数据库了,导致后面的外键无法被满足。
为了解决这个问题,我们采用延迟提交给数据库的方式:
def store_add(req):
if req.method == 'POST':
...
if sf.is_valid() and af.is_valid() and df.is_valid():
form = sf.save(commit=False)
sf.save()
dform = df.save(commit=False)
dform.s_name = form
dform.save()
aform = af.save(commit=False)
aform.s_name = form
aform.save()
return HttpResponseRedirect('store')
else:
...
在这里,我们先让第1张表先不提交,将其保存为1个变量form中。而第2个张表也先不提交,我们将其实例的s_name修改为之前的第1张表返回的结果,然后再进行保存。这样我们就实现了多张表的依赖导致的问题了。最后我们使用重定向的方式将成功添加后的页面跳转到该商户的仓库列表中。
其跳转后的页面如下所示:
这样我们就解决了在1个页面提交多个表单的问题。实际关于Django在1个页面提交多个表单的问题,实际上问题不是很多,只要解决了渲染和提交时处理的问题,实际这个问题就迎刃而解了。重要的是如何拆分问题和解决问题的思路。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# django
# 表单处理
# 表单
# form表单
# Django之模型层多表操作的实现
# django 多对多表的创建和插入代码实现
# django多对多表的创建
# 级联删除及手动创建第三张表
# 解决django中ModelForm多表单组合的问题
# Django实现一对多表模型的跨表查询方法
# Django框架多表查询实例分析
# Django模型层实现多表关系创建和多表操作
# 多个
# 在这里
# 所示
# 这个问题
# 将其
# 你能
# 就把
# 可以看到
# 解决了
# 文档
# 跳转
# 来实现
# 商户
# 自己的
# 的是
# 完成了
# 我就
# 使用了
# 主要有
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全
香港网站服务器数量如何影响SEO优化效果?
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
成都网站制作公司哪家好,四川省职工服务网是做什么用?
Laravel如何编写单元测试和功能测试?(PHPUnit示例)
如何快速使用云服务器搭建个人网站?
如何快速建站并高效导出源代码?
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
如何快速查询域名建站关键信息?
Laravel如何记录自定义日志?(Log频道配置)
微信h5制作网站有哪些,免费微信H5页面制作工具?
如何挑选高效建站主机与优质域名?
历史网站制作软件,华为如何找回被删除的网站?
Python图片处理进阶教程_Pillow滤镜与图像增强
如何在阿里云虚拟主机上快速搭建个人网站?
动图在线制作网站有哪些,滑动动图图集怎么做?
Laravel如何为API编写文档_Laravel API文档生成与维护方法
Laravel如何实现用户注册和登录?(Auth脚手架指南)
米侠浏览器网页图片不显示怎么办 米侠图片加载修复
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
昵图网官网入口 昵图网素材平台官方入口
使用豆包 AI 辅助进行简单网页 HTML 结构设计
手机软键盘弹出时影响布局的解决方法
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
如何在IIS7中新建站点?详细步骤解析
打造顶配客厅影院,这份100寸电视推荐名单请查收
Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧
高性能网站服务器部署指南:稳定运行与安全配置优化方案
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
Laravel如何为API生成Swagger或OpenAPI文档
如何在万网开始建站?分步指南解析
bootstrap日历插件datetimepicker使用方法
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
Python文件操作最佳实践_稳定性说明【指导】
高防服务器租用如何选择配置与防御等级?
Laravel如何配置任务调度?(Cron Job示例)
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
ChatGPT 4.0官网入口地址 ChatGPT在线体验官网
如何基于PHP生成高效IDC网络公司建站源码?
Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】
Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验
在线教育网站制作平台,山西立德教育官网?
佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】
QQ浏览器网页版登录入口 个人中心在线进入
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤
Edge浏览器怎么启用睡眠标签页_节省电脑内存占用优化技巧

