web2py:多个表:从一个表单进行条件插入/更新/删除
我写了一段代码,用于通过一个表单来管理多个表的条件插入、更新和删除,这个是在'web2py'框架下做的。虽然我承认这段代码写得很粗糙,可能不太符合Python的风格,而且有些地方重复了代码,但至少我有了一个基础,可以在此基础上进一步完善结构。
模型:
db.define_table('mdlmst',
Field('mdlmstid','id'),
Field('mdlmstcd'),
Field('mdlmstnm'),
migrate=False,
format='%(mdlmstnm)s'
)
db.define_table('wrmst', Field('wrmstid','id'), Field('wrmstcd'), Field('wrmstnm'), migrate=False, format='%(wrmstnm)s' )
db.define_table('extwrmst', Field('extwrmstid','id'), Field('extwrmstcd'), Field('extwrmstnm'), migrate=False, format='%(extwrmstnm)s' )
从表单中,数据将填充到以下两个表中
db.define_table('mdlwr',
Field('mdlwrid','id'),
Field('mdlmstid',db.mdlmst),
Field('wrmstid',db.wrmst),
migrate=False
)
db.define_table('mdlextwr', Field('mdlextwrid','id'), Field('mdlmstid',db.mdlmst), Field('extwrmstid',db.extwrmst), migrate=False )
控制器:
‘modelwar’控制器将展示‘mdlmst’表中的记录
def modelwar():
models = db(db.mdlmst.mdlmstid>0).select(orderby=db.mdlmst.mdlmstnm)
return dict(models=models)
点击某条记录后,‘war_edit’控制器将
管理‘mdlwr’和‘mdlextwr’这两个表
def war_edit():
mdl_id = request.args(0)
mdl_id是一个变量,用来标识‘mdlmstid’(要修改的记录)
mdl_nm = request.args(1)
mdl_nm是一个变量,用来获取‘mdlmstnm’
warset = db(db.mdlwr.mdlmstid==mdl_id) # fetch a set
extwarset = db(db.mdlextwr.mdlmstid==mdl_id) # fetch a set
warlist = db(db.mdlwr.mdlmstid==mdl_id).select() # get a ROW object
extwarlist = db(db.mdlextwr.mdlmstid==mdl_id).select() # get a ROW object
form_war=FORM(TABLE(TR("Basic Warranty",
SELECT(_type="select",_name="baswar",*[OPTION(x.wrmstnm,_value=x.wrmstid) for x in db().select(db.wrmst.ALL)]), TR("扩展保修", SELECT(_type="select",_name="extwar",*[OPTION(x.extwrmstnm,_value=x.extwrmstid) for x in db().select(db.extwrmst.ALL)]), TR("", INPUT(_type='submit',_value='保存')), ))))
预填充‘form_war’中的字段
if len(warlist)>0:
form_war.vars.baswar = warlist[0].wrmstid
if len(extwarlist)>0:
form_war.vars.extwar = extwarlist[0].extwrmstid
成功提交表单后,管理‘mdlwr’表
if form_war.accepts(request.vars, session):
如果从数据库中获取的记录列表中有任何记录,并且发送到表单中,
if len(warlist)>0:
如果表单字段返回的值是空的,就删除记录,否则更新记录
if form_war.vars.baswar==''
warset.delete()
else:
warset.update(wrmstid=form_war.vars.baswar)
否则插入新记录
else:
db.mdlwr.insert(mdlmstid=mdl_id, wrmstid=form_war.vars.baswar)
同样,管理‘mdlextwr’表
if len(extwarlist)>0:
if form_war.vars.extwar=='':
extwarset.delete()
else:
extwarset.update(extwrmstid=form_war.vars.extwar)
else:
db.mdlextwr.insert(mdlmstid=mdl_id, extwrmstid=form_war.vars.extwar)
response.flash = 'Warranty definition saved'
return dict(form_war=form_war,mdlnm=mdl_nm)
‘mdlmst’表的视图
{{response.files.append(URL(r=request,c='static',f='jquery.dataTables.min.j
s'))}}
{{response.files.append(URL(r=request,c='static',f='demo_table.css'))}}
{{extend 'layout.html'}}
jQuery(document).ready(function()
{ jQuery('.smarttable').dataTable();});
按模型分类的保修主表
模型ID模型代码模型名称 {{for model in models:}} {{=model.mdlmstid}} {{=model.mdlmstcd}} {{=model.mdlmstnm}} {{=A('编辑保修',_href=URL('war_edit',args=[model.mdlmstid,model.mdlmstnm]))}} {{pass}}请告诉我这里有没有写得不好的地方。我非常欢迎任何改进的想法或建议。
谢谢, Vineet
1 个回答
你的数据库设计看起来有点奇怪。
在每个表里,你都有一个叫做'id'的字段。这个字段会替代web2py自动生成的'id'字段,这样做不好。根据web2py的书上说:"不要声明一个叫做'id'的字段,因为web2py会自动创建一个。每个表默认都有一个'id'字段。这个字段是一个自增的整数(从1开始),用来做交叉引用和确保每条记录都是唯一的,所以'id'是主键"
你在'mdlmst'表和'wrmst'表之间创建了一个多对多的关系,同时在'mdlmst'和'extwrmst'之间也创建了另一个多对多的关系。虽然这样做不一定错,但我觉得这很可能不是你想要的。
我觉得你的数据库设计需要改进。在你开始设计表单之前,最好先把这些问题解决掉。