The "onvalidation" function is supposed to be called "upon validation" (hence the name), meaning after a successful validation of the submitted field values. It is not intended to be run in order to make checks before or after deletion of a record. In other words, onvalidation runs when particular conditions are met, and it does so consistently. It just so happens that you want to run it under different conditions, which is not its intended purpose. Even if it did run when you want, you would still need a way to distinguish a regular update request from a delete request, and you can do that just as easily outside of the onvalidation function (see below).
I think there are three types of cases to handle regarding deletes:
First, you might want to simply allow/disallow a delete, and that case is handled by the "deletable" argument.
Second, you might want to run some code after a successful delete. The grid has an "ondelete" argument to handle that in case the "Delete" button is clicked, but nothing for the case when a delete happens via an edit form. However, this can be handled in all cases via the db.mytable._after_delete callback. In any case, the onvalidation function would not be the best place for this logic as it (a) runs before the delete happens, and (b) would still require some logic to determine that a delete was requested. It might be nice if SQLFORM had a separate "ondelete" argument of its own.
Finally, you might want to allow the user to request a delete and then kick off a separate workflow, such as requiring a special password. However, that is really a special case that is application specific, and it is not even well accommodated by the current UI (i.e., it would be a better user experience to request the special password up front rather than making it a two step process). If you need something like that, you should really be implementing custom logic. And again, the onvalidation function is not the best place for such logic, as it would still require detection of the delete request.
As an aside, note that the "onvalidation" argument can actually be a dictionary with separate "onsuccess", "onfailure", and "onchange" callbacks. The grid also has "onupdate" (run after successful update) and "onfailure" (run after failed update) arguments, as well as the "ondelete" argument. Some combination of these callbacks could be used to run some code whenever a delete is requested, though it is probably simpler to just do a check like the following before calling grid():
if SQLFORM.FIELDNAME_REQUEST_DELETE in request.post_vars or 'delete' in request.args:
[code to handle delete workflow]
Anthony