web2py 记录 ID 未传递给 SQLFORM 的 onvalidation 函数
web2py record id not being passed to onvalidation function for SQLFORM
我试图通过调用不同的 SQLFORM 来使用相同的控制器函数进行插入和更新,具体取决于传递给函数的参数是否存在:
def manage_doc():
db.doc_master.sr_no.readable=False
db.doc_master.sr_no.writable=False
if not len(request.args):
form = SQLFORM(db.doc_master)
else:
doc_to_edit = db.doc_master(request.args[0])
form = SQLFORM(db.doc_master, doc_to_edit)
if form.process(onvalidation=check_form_manage_doc).accepted:
if not len(request.args):
session.flash = 'Document added'
else:
session.flash = 'Document updated'
redirect(URL('index'))
return dict(form=form)
这是 onvalidation 回调:
def check_form_manage_doc(form):
new_inward_no = form.vars.inward_no
new_inward_year = form.vars.inward_date.year
if (form.vars.doc_date > form.vars.inward_date):
form.errors.doc_date = 'Document Date cannot be later than Inward Date'
rows = db(db.doc_master.inward_date.year() == new_inward_year)
for row in rows.select():
if ((row.id != form.vars.id) and (row.inward_no == new_inward_no)):
form.errors.inward_no = 'Inward No %s already exists for Doc %s' % (str(new_inward_no), str(form.vars.id))
form.vars.sr_no = str(new_inward_no)+'/'+str(new_inward_year)
虽然该函数在插入时工作正常,但在更新时失败,因为 form.vars.id
在回调函数中始终是 None
。我的代码有什么问题?
form.vars.id
在 onvalidation
为 运行 时未填充。您可以改为使用 request.post_vars.id
,它当然会继续是 None
用于记录创建,但将包含用于更新的记录 ID(request.post_vars.id
将是一个字符串,因此转换为 int
当不是 None
).
顺便说一句,请注意没有理由有条件地创建两种不同的形式——您可以简单地做:
form = SQLFORM(db.doc_master, record=request.args(0))
如果没有 URL 参数,request.args(0)
将只是 None
。另外,请注意 record
参数可以只是记录 ID 而不是包含记录的 DAL Row
对象。
另外,请注意 .process
方法包含一些参数,可以进一步简化您的代码——您的所有表单代码都可以替换为:
form = SQLFORM(db.doc_master, request.args(0)).process(
onvalidation=check_form_manage_doc,
message_onsuccess='Document %s' % ('updated' if request.args else 'added'),
next=URL('index'))
我试图通过调用不同的 SQLFORM 来使用相同的控制器函数进行插入和更新,具体取决于传递给函数的参数是否存在:
def manage_doc():
db.doc_master.sr_no.readable=False
db.doc_master.sr_no.writable=False
if not len(request.args):
form = SQLFORM(db.doc_master)
else:
doc_to_edit = db.doc_master(request.args[0])
form = SQLFORM(db.doc_master, doc_to_edit)
if form.process(onvalidation=check_form_manage_doc).accepted:
if not len(request.args):
session.flash = 'Document added'
else:
session.flash = 'Document updated'
redirect(URL('index'))
return dict(form=form)
这是 onvalidation 回调:
def check_form_manage_doc(form):
new_inward_no = form.vars.inward_no
new_inward_year = form.vars.inward_date.year
if (form.vars.doc_date > form.vars.inward_date):
form.errors.doc_date = 'Document Date cannot be later than Inward Date'
rows = db(db.doc_master.inward_date.year() == new_inward_year)
for row in rows.select():
if ((row.id != form.vars.id) and (row.inward_no == new_inward_no)):
form.errors.inward_no = 'Inward No %s already exists for Doc %s' % (str(new_inward_no), str(form.vars.id))
form.vars.sr_no = str(new_inward_no)+'/'+str(new_inward_year)
虽然该函数在插入时工作正常,但在更新时失败,因为 form.vars.id
在回调函数中始终是 None
。我的代码有什么问题?
form.vars.id
在 onvalidation
为 运行 时未填充。您可以改为使用 request.post_vars.id
,它当然会继续是 None
用于记录创建,但将包含用于更新的记录 ID(request.post_vars.id
将是一个字符串,因此转换为 int
当不是 None
).
顺便说一句,请注意没有理由有条件地创建两种不同的形式——您可以简单地做:
form = SQLFORM(db.doc_master, record=request.args(0))
如果没有 URL 参数,request.args(0)
将只是 None
。另外,请注意 record
参数可以只是记录 ID 而不是包含记录的 DAL Row
对象。
另外,请注意 .process
方法包含一些参数,可以进一步简化您的代码——您的所有表单代码都可以替换为:
form = SQLFORM(db.doc_master, request.args(0)).process(
onvalidation=check_form_manage_doc,
message_onsuccess='Document %s' % ('updated' if request.args else 'added'),
next=URL('index'))