快速上手Django实现项目
近期公司在做1个海淘的项目,APP为pylot。由于时间比较赶,加上隔壁那哥们不在,只能自己挑大梁了。结果,当项目做出来之后,被领导狠狠的批了一顿,说怎么用django写,你能解决Django的内存问题吗,你能解决并发的问题吗"color: #ff0000">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个页面提交多个表单的问题,实际上问题不是很多,只要解决了渲染和提交时处理的问题,实际这个问题就迎刃而解了。重要的是如何拆分问题和解决问题的思路。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。