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.
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 [email protected].
For more options, visit https://groups.google.com/d/optout.