• Flask_admin 笔记六 modelView的内置方法


    增加model后端
    Flask-Admin对与之配合的数据库模型做了一些假设。 如果要实现自己的数据库后端,并且Flask-Admin的模型视图仍可按预期工作,则应注意以下事项:
    1) 每一个model必须有主键,但不限定数据类型和主键名
    2) 确保每一个model的属性都是可以访问的

    在此基础上,你可以通过继承BaseMiodelView类来实现数据库后端的扩展,并实现下面列出的一系列方法:
    1 扩展BaseModelView
    首先定义一个从BaseModelView派生的新类:

    class MyDbModel(BaseModelView):
            pass

    这个类继承了BaseModelView的__init__方法,它接受一个模型类作为第一个参数。 模型类存储为属性self.model,以便其他方法可以访问它。

    现在,为新的类实现以下脚手架方法:
    1.1 get_pk_value()
    该方法从模型实例中返回一个主键值。 在SQLAlchemy后端,它使用scaffold_pk()从模型获得主键,缓存它,然后在需要时从模型返回值。
    例子:

    class MyDbModel(BaseModelView):
        def get_pk_value(self, model):
        return self.model.id

    1.2 scaffold_list_columns()
    返回列表视图要展示的列。例子:

    class MyDbModel(BaseModelView):
        def scaffold_list_columns(self):
              columns = []
    
              for p in dir(self.model):
                attr = getattr(self.model, p)
                if isinstance(attr, MyDbColumn):
                    columns.append(p)
    
               return columns

    1.3 scaffold_sortable_columns()
    返回可排序列的字典。 字典中的键应该对应于模型的字段名称。 值应该是那些将用于排序的变量。

    例如,在SQLAlchemy后端可以按外键字段进行排序。 所以,如果有一个名为user的字段,它是Users表的一个外键,并且Users表也有一个名称字段,那么这个键将是user的value将是:Users.name。

    如果您的后端不支持排序,则返回None或空字典。

    1.4 init_search()
    初始化搜索功能。 如果您的后端支持全文搜索,请进行初始化并返回True。 如果您的后端不支持全文搜索,请返回False。

    例如,SQLAlchemy后端读取self.searchable_columns的值,并验证是否所有字段都是文本类型,如果它们定位到当前的模型(如果不是,则会添加一个连接等)并缓存这些信息以备将来使用。
    1.5 scaffold_form()
    在模型里定义WTForms表单,例子:

    class MyDbModel(BaseModelView):
            def scaffold_form(self):
            class MyForm(Form):
                  pass
    
          # Do something
           return MyForm

    1.6 get_list()
    这个方法应该返回带有分页,排序等应用的模型实例列表。

    对于SQLAlchemy后端,它看起来像:
    1)如果搜索已启用且提供的搜索值不为空,将会为self.searchable_columns中的每个字段生成LIKE语句

    2)如果传递过滤值,请使用值调用apply方法:

    for flt, value in filters:
        query = self._filters[flt].apply(query, value)

    3)执行查询获取数据库中的总行数(count)
    4)如果sort_column被传递,会做类似的事情(带有一些额外的FK逻辑,在这个例子中省略):

    if sort_desc:
         query = query.order_by(desc(sort_field))
    else:
         query = query.order_by(sort_field)

    5)应用分页
    6)返回总条数和列表的元组

    1.7 get_one()
    根据主键返回model数据
    1.8 create_model()
    通过表单创建一个model的实例
    1.9 update_model()
    更新表单model的实例
    1.10 delete_model()
    从数据存储中删除特定的model数据
    1.11 is_valid_filter()
    验证返回的数据是否是有效的
    1.12scaffold_filters()
    返回一个模型字段的过滤器对象列表。
    对于self.column_filters设置中的每个条目,该方法都会被调用一次。
    如果后端不知道如何为提供的字段生成过滤器,则应该返回None。

    例如:

    class MyDbModel(BaseModelView):
           def scaffold_filters(self, name):
           attr = getattr(self.model, name)
    
            if isinstance(attr, MyDbTextField):
            return [MyEqualFilter(name, name)]

    2,实现过滤
    每个模型后端都应该有自己的一组过滤器实现。 在非SQLAlchemy后端不能使用SQLAlchemy模型中的过滤器。 这也意味着不同的后端可能有不同的可用过滤器集合。

    过滤器是从BaseFilter派生的类,它实现了至少两种方法:
    1. apply()
    2. operation()
    apply方法接受两个参数:查询对象和来自客户端的值。 在这里您可以为过滤器类型添加过滤逻辑。

    让我们以SQLAlchemy模型后端为例:
    所有SQLAlchemy过滤器都从BaseSQLAFilter类派生。
    每个过滤器都实现一个简单的过滤器SQL操作(如,not like,大于等),并接受一列作为输入参数。每当模型视图要将筛选器应用于查询对象时,它将在具有查询和值的筛选器类中调用apply方法。 过滤器将应用实际的过滤器操作。

    class MyBaseFilter(BaseFilter):
        def __init__(self, column, name, options=None, data_type=None):
            super(MyBaseFilter, self).__init__(name, options, data_type)
    
            self.column = column
    
    class MyEqualFilter(MyBaseFilter):
        def apply(self, query, value):
            return query.filter(self.column == value)
    
        def operation(self):
            return gettext('equals')
    
        # You can validate values. If value is not valid,
        # return `False`, so filter will be ignored.
        def validate(self, value):
            return True
    
        # You can "clean" values before they will be
        # passed to the your data access layer
        def clean(self, value):
            return value

    如果您在添加新模型后端时遇到问题,请随时提问。 此外,如果遇到困难,请尝试查看SQLAlchemy模型后端并将其用作参考。

  • 相关阅读:
    二分查找
    Uva11464 Even Parity
    Uva10881 Piotr's Ants
    POJ3154 Graveyard
    [NOIP2015] 提高组 洛谷P2680 运输计划
    [NOIP2015] 提高组 洛谷P2679 子串
    [NOIP2015] 提高组 洛谷P2678 跳石头
    [NOIP2015] 提高组 洛谷P2668 斗地主
    [NOIP2015] 提高组 洛谷P2661 信息传递
    [NOIP2015] 提高组 洛谷P2615 神奇的幻方
  • 原文地址:https://www.cnblogs.com/minsons/p/8143921.html
Copyright © 2020-2023  润新知