Search code examples
pythonflask-admin

How to override delete logic on Flask Admin?


I have been searching on Google and StackOverflow about this. Basically, I want to try and override the delete function on Flask-Admin to not actually delete a record, but instead update a row of the object called 'deleted_by' and 'deleted_on'.

I have found a few questions on StackOverflow that explain how to change the logic on the save button by using on_model_change, but no one specific about the delete model logic. I have also not found any information regarding this on the documentation. Could anyone show me how should I handle this issue?

Thanks in advance!


Solution

  • Override method delete_model in your view. Here is the default behaviour if you are using Sqlalchemy views, note the call to self.session.delete(model) in the try ... except block.

    def delete_model(self, model):
        """
            Delete model.
            :param model:
                Model to delete
        """
        try:
            self.on_model_delete(model)
            self.session.flush()
            self.session.delete(model)
            self.session.commit()
        except Exception as ex:
            if not self.handle_view_exception(ex):
                flash(gettext('Failed to delete record. %(error)s', error=str(ex)), 'error')
                log.exception('Failed to delete record.')
    
            self.session.rollback()
    
            return False
        else:
            self.after_model_delete(model)
    
        return True
    

    You would need something like the following in your view:

    class MyModelView(ModelView):
    
    
       def delete_model(self, model):
            """
                Delete model.
                :param model:
                    Model to delete
            """
            try:
                self.on_model_delete(model)
                # Add your custom logic here and don't forget to commit any changes e.g. 
                # self.session.commit()
            except Exception as ex:
                if not self.handle_view_exception(ex):
                    flash(gettext('Failed to delete record. %(error)s', error=str(ex)), 'error')
                    log.exception('Failed to delete record.')
    
                self.session.rollback()
    
                return False
            else:
                self.after_model_delete(model)
    
            return True
    

    Also, you might not want to bother with the self.on_model_delete(model) and self.after_model_delete(model) calls because by default they do nothing.