有条件地允许在Flask admin ModelView的列表视图中进行编辑

有条件地允许在Flask admin ModelView的列表视图中进行编辑,flask,edit,flask-admin,Flask,Edit,Flask Admin,我可以在view类中具有这样的属性: class MyExampleView(ModelView): @property def can_edit(self): # Return True or False based on some conditional logic 如何访问该行的属性,例如,如果该行的处于活动状态,则可以有条件地在表中显示编辑列属性为True或False。您可以通过一些模板操作增强功能来实现,其中添加了一个检查行可用性的方法: from

我可以在view类中具有这样的属性:

class MyExampleView(ModelView):

    @property
    def can_edit(self):
        # Return True or False based on some conditional logic

如何访问该行的属性,例如,如果该行的
处于活动状态,则可以有条件地在表中显示编辑列
属性为True或False。

您可以通过一些模板操作增强功能来实现,其中添加了一个检查行可用性的方法:

from flask_admin.model import template

class AccessMixin:
    def has_access(self, row):
        raise NotImplementedError()

class ViewRowAction(template.ViewRowAction, AccessMixin):
    def has_access(self, row):
        return True

class EditRowAction(template.EditRowAction, AccessMixin):
    def has_access(self, row):
        return row.is_active

class DeleteRowAction(template.DeleteRowAction, AccessMixin):
    def has_access(self, row):
        return row.is_active
然后您需要覆盖
list.html
模板中的
list\u row\u操作
块以使用此新方法:

{% extends 'admin/model/list.html' %}

{% block list_row_actions scoped %}
  {% for action in list_row_actions %}
    {% if action.has_access(row) %}
      {{ action.render_ctx(get_pk_value(row), row) }}
    {% endif %}
  {% endfor %}
{% endblock %}
然后,您需要模型类使用覆盖的行操作和列表模板:

from flask_admin.contrib.sqla.view import ModelView

class MyExampleView(ModelView):
    list_template = 'app_list.html'

    def get_list_row_actions(self):
        return (
            ViewRowAction(),
            EditRowAction(),
            DeleteRowAction(),
        )
请注意,原始的
get\u list\u row\u actions
方法使用
can\u view\u details
can\u edit
can\u delete
details\u modal
edit\u modal
属性来定义所用操作的列表。您可以通过重写它来放弃此逻辑

此外,它不会阻止用户实际编辑或删除对象(例如,通过在浏览器中手动键入编辑视图URL)。您需要在视图方法中实现访问权限检查,例如:

from flask import flash, redirect, request
from flask_admin import expose
from flask_admin.babel import gettext
from flask_admin.helpers import get_redirect_target
from flask_admin.model.helpers import get_mdict_item_or_list

class MyExampleView(ModelView):
    @expose('/edit/', methods=('GET', 'POST'))
    def edit_view(self):
        """This code was copied from the
           flask_admin.model.base.BaseModelView.edit_view method"""
        return_url = get_redirect_target() or self.get_url('.index_view')

        id = get_mdict_item_or_list(request.args, 'id')
        if id is None:
            return redirect(return_url)

        model = self.get_one(id)

        if model is None or not model.is_active:
            flash(gettext('Record does not exist or you have 
                          not enough access rights.'), 'error')
            return redirect(return_url)

        return super(MyExampleView, self).edit_view()