I was able to solve it with the SQLFORM.factory hidden parameter.
grid = SQLFORM.grid(
query,
csv=False, deletable=False, details=False,
links=[
lambda row: A(
SPAN(T('Delete'), _class='buttontext button', _title='Delete'),
_href=URL('get_approval', args=[row.id], user_signature=True),
_class='button btn btn-default btn-secondary',
),
],
onvalidation=on_validation, # Form only.
orderby=db.client.name,
paginate=session.auth.user.pagination,
# represent_none='', # Grid and view form only.
)
if 'edit' in request.args:
form = grid.update_form
form['hidden'].update(modified_on=form.record.modified_on)
if request.args and request.args[0] == 'new':
# Fix for SQLite instead of for_update=True. When for_update is
# fixed for SQLite, only the first SELECT in the function should
# have for_update=True.
while True:
try:
# SQLite only does database lock.
db.executesql('BEGIN IMMEDIATE TRANSACTION')
break
except sqlite3.OperationalError:
sleep(0.5)
elif not db.client(request.vars.id).is_active:
session.flash = T('Record was deleted while you were editing.')
redirect(URL(user_signature=True))
elif request.post_vars.modified_on != str(db.client(request.vars.id).modified_on):
form.errors.code = T('Record was changed while you were editing. '
'Press F5 to refresh and press Resend in the '
'browser question.')
elif form.vars.delete_this_record:
# Fix for SQLite instead of for_update=True. When for_update is
# fixed for SQLite, only the first SELECT in the function should
# have for_update=True.
while True:
try:
# SQLite only does database lock.
db.executesql('BEGIN IMMEDIATE TRANSACTION')
break
except sqlite3.OperationalError:
sleep(0.5)
db.client(request.vars.id).update_record(
cancel_approved_by=auth.user_id,
canceled_by=auth.user_id,
canceled_on=request.now,
is_active=False,
)
db.commit()
session.flash = T('Done.')
redirect(URL(user_signature=True))
elif request.args and request.args[0] == 'edit':
# Fix for SQLite instead of for_update=True. When for_update is
# fixed for SQLite, only the first SELECT in the function should
# have for_update=True.
while True:
try:
# SQLite only does database lock.
db.executesql('BEGIN IMMEDIATE TRANSACTION')
break
except sqlite3.OperationalError:
sleep(0.5)
elif request.args and request.args[0] == 'edit':
if request.vars.modified_on != str(form.record.modified_on):
session.flash = 'Record change detected. Please try again.'
redirect(URL(args=request.args, vars=request.get_vars))
elif request.post_vars.modified_on != str(db.client(request.vars.id).modified_on):
form.errors.code = T('Record was changed while you were editing. '
'Press F5 to refresh and press Resend in the '
'browser question.')
elif request.post_vars.modified_on != str(db.client(request.vars.id).modified_on):
session.flash = T('Record was changed while you were editing. '
'This is the updated record.')
redirect(URL(args=request.args, vars=request.get_vars, user_signature=True))
which I changed now to this
elif request.post_vars.modified_on != str(db.client(request.vars.id).modified_on):
session.flash = T('Record was changed while you were editing. '
'This is the updated record.')
redirect(URL(args=request.args, vars=request.get_vars, user_signature=True))
def on_validation(form: SQLFORM) -> None:
"""Used in the edit form, including when creating and deleting.
:param form: Form.
"""
# Fix for SQLite instead of for_update=True. When for_update is
# fixed for SQLite, only the first SELECT in the function should
# have for_update=True.
while True:
try:
# SQLite only does database lock.
db.executesql('BEGIN IMMEDIATE TRANSACTION')
break
except sqlite3.OperationalError:
sleep(0.5)
if request.args and request.args[0] == 'new':
if db.wo_counter(year_=request.now.year):
form.errors.last_assigned = T('Counter already exists')
else: # Edit/delete.
if (not form.record.is_active and not form.vars.delete_this_record
and auth.has_membership(SUPERVISOR_ROLE)):
db.wo_counter(request.vars.id).update_record(
cancel_approved_by=None,
canceled_by=None,
canceled_on=None,
is_active=True,
)
db.commit()
session.flash = T('Record was activated.')
redirect(URL('index', user_signature=True))
elif not form.record.is_active:
session.flash = T('Record was deleted while you were editing.')
redirect(URL('index', user_signature=True))
elif (request.post_vars.modified_on != str(form.record.modified_on)):
session.flash = T('Record was changed while you were editing. '
'This is the updated record.')
redirect(URL(args=request.args, vars=request.get_vars, user_signature=True))
elif db.wo_counter(request.args[-1]).last_assigned > form.vars.last_assigned:
form.errors.last_assigned = T('New value must >= than old.')
elif form.vars.delete_this_record:
db.wo_counter(request.vars.id).update_record(
cancel_approved_by=auth.user_id,
canceled_by=auth.user_id,
canceled_on=request.now,
is_active=False,
)
db.commit()
session.flash = T('Done.')
redirect(URL(user_signature=True))
elif request.post_vars.modified_on != str(form.record.modified_on):
session.flash = T('Record was changed while you were editing. '
'This is the updated record.')
redirect(URL(args=request.args, vars=request.get_vars, user_signature=True))
elif session.client_modified_on != form.record.modified_on: session.client_modified_on = form.record.modified_on
session.flash = T('Record was changed while you were editing. '
'This is the updated record.')
redirect(URL(args=request.args, vars=request.get_vars, user_signature=True))
if 'edit' in request.args:
form = grid.update_form
form['hidden'].update(modified_on=form.record.modified_on)
if 'edit' in request.args:
form = grid.
update_form
#form['hidden'].update(modified_on=form.record.modified_on)
if not session.client_modified_on:
session.client_modified_on = form.record.modified_on
elif 'edit' not in request.args and session.client_modified_on:
del session.client_modified_on