Search code examples
pythonflaskflask-sqlalchemyflask-loginflask-admin

Customizing the flask admin row actions


I want to add another button next to the edit and delete icons on flask admin list view. In addition, I want to send that row data to a route as a post request. I know that I have to edit the admin/model/list.html template, but I am not getting how to add this functionalities.

Can you provide any guidance?

this is current default view for admin page


Solution

  • You need to define custom action buttons for your view. This process is not described in the Flask-Admin tutorial but it is mentioned in the API description.

    POST method

    If you need to create a button for a POST method you should implement a jinja2 macro like this delete_row action. It may look like this (I named the file "custom_row_actions.html"):

    {% macro copy_row(action, row_id, row) %}
    <form class="icon" method="POST" action="{{ get_url('.copy_view') }}">
      <input type="hidden" name="row_id" value="{{ get_pk_value(row) }}"/>
      <button type="submit" title="{{ _gettext('Copy record') }}">
        <span class="glyphicon glyphicon-copy"></span>
      </button>
    </form>
    {% endmacro %}
    

    Then you create a template for your list of records and import the macro library in it (I named it "my_list.html"):

    {% extends 'admin/model/list.html' %}
    {% import 'custom_row_actions.html' as custom_row_actions with context %}
    

    After that you have to make a couple of changes in your view:

    from flask_admin import expose
    from flask_admin.contrib.sqla.view import ModelView
    from flask_admin.model.template import TemplateLinkRowAction
    
    class MyView(ModelView):
        list_template = "my_list.html"  # Override the default template
        column_extra_row_actions = [  # Add a new action button
            TemplateLinkRowAction("custom_row_actions.copy_row", "Copy Record"),
        ]
    
        @expose("/copy", methods=("POST",))
        def copy_view(self):
            """The method you need to call"""
    

    GET method

    Creating a button for a GET method is much simpler. You don't need to override templates, just add an action to your view:

    from flask_admin import expose
    from flask_admin.contrib.sqla.view import ModelView
    from flask_admin.model.template import EndpointLinkRowAction
    
    class MyView(ModelView):
        column_extra_row_actions = [  # Add a new action button
            EndpointLinkRowAction("glyphicon glyphicon-copy", ".copy_view"),
        ]
    
        @expose("/copy", methods=("GET",))
        def copy_view(self):
            """The method you need to call"""
    

    Glyphicons

    Glyphicons is the icon library which is bundled with the Bootstrap v3 library which is used by the Flask-Admin. You can use it if you chose this Bootstrap version on Flask-Admin initialization:

    from flask_admin import Admin
    
    admin = Admin(template_mode="bootstrap3")
    

    You can look at the available icons in the Bootsrap v3 documentation.