brilliant as always, never thought that the callback can be rearranged on the list. thank you so much Anthony for show me the way.
best regards, stifan On Sunday, April 12, 2015 at 8:48:06 AM UTC+7, Anthony wrote: > > OK, the problem is that with record versioning, there is a common filter > applied that excludes records with is_active=False. The _after_update > callback gets called *after* the is_active field has been set to False > (which happens when the table's _before_delete callback is called). As a > result, the records in question no longer show up in the select. > > The best workaround is probably to use the _before_delete callback rather > than the _after_update callback. In the module: > > def after_update_event(s, f, table): > if not ('is_active' in f and f['is_active'] == False) and '_archive' > not in table: > table_input = s.select().first() > current.db.auth_event.insert(time_stamp=current.request.now, > client_ip=current.request.client, > user_id=current.auth.user_id, > origin='%s/%s' %(current.request. > controller, > current.request. > function), > description='ID %s updated in table > %s' % (table_input.id, table)) > > def before_delete_event(s, table): > table_input = s.select().first() > if table_input and '_archive' not in table: > current.db.auth_event.insert(time_stamp=current.request.now, > client_ip=current.request.client, > user_id=current.auth.user_id, > origin = '%s/%s' % (current.request. > controller, > current.request. > function), > description='ID %s deleted in table > %s' % (table_input.id, table)) > > Note, I also added a condition to exclude the '_archive' tables, as you > probably don't want to log that activity. > > In the model file: > > for table in db.tables: > if table != 'auth_event': > db[table]._after_insert.append(partial(test_event. > after_insert_event, table=table)) > db[table]._after_update.append(partial(test_event. > after_update_event, table=table)) > db[table]._before_delete.insert(0, partial(test_event. > before_delete_event, table=table)) > > Note, you must insert the _before_delete callback at the beginning of the > list so it gets called before the is_active field is set to False. > > The only downside to this approach is that if a subsequent _before_delete > callback causes the delete (i.e., update to is_active=False) to be aborted, > then the delete will still get logged, even though it didn't actually > happen. If you are using additional callbacks and that is a concern, a > workaround might be to have the _before_delete callback store the ID of the > deleted record in the session (but don't log the delete at that point). > Then, in the _after_update callback, in the case of setting > is_active=False, fetch the ID from the session and log the delete at that > point. > > Anthony > > > On Friday, April 10, 2015 at 8:12:48 PM UTC-4, 黄祥 wrote: >> >> this min app is work fine, but when you change in modules/test_event.py : >> description = 'ID %s deleted in table %s' % (*s*, table) >> into >> description = 'ID %s deleted in table %s' % (*table_input.id >> <http://table_input.id>*, table) >> >> it got an error : >> >> description = 'ID %s deleted in table %s' % (table_input.id, table) ) >> AttributeError: 'NoneType' object has no attribute 'id' >> >> thanks and best regards, >> stifan >> >>> -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.