gpt4 book ai didi

python - 向应用程序工厂注册 flask 管理 View 的正确方法

转载 作者:行者123 更新时间:2023-12-03 16:56:10 25 4
gpt4 key购买 nike

我正在使用应用程序工厂向我的 flask 应用程序添加 View ,如下所示:

(这不是我的实际应用工厂,为了简洁起见已缩短)

def create_app(config_name='default'):
app = Flask(__name__, template_folder="templates", static_folder='static')
admin_instance = Admin(app, name='Admin')
admin_instance.add_view(EntityAdmin(Entity, db.session))

我的 EntityAdmin 类如下所示:
class EntityAdmin(ModelView):
column_filters = [
MyCustomFilter(column=None, name='Custom')
]

我的自定义过滤器如下所示:
class MyCustomFilter(BaseSQLAFilter):
def get_options(self, view):
entities = Entity.query.filter(Entity.active == True).all()
return [(entity.id, entity.name) for entity in entities]

问题是,似乎 get_options函数在实例化应用程序时调用,每次运行选择查询 create_app函数被调用。

因此,如果我更新我的数据库架构并运行 flask db migrate命令,我收到一个错误,因为在运行选择查询时我添加的新列不存在。该查询引发错误,因为我的数据库架构与实际数据库不同步。

我可以仅在发出实际 HTTP 请求时注册我的 View 吗?如何区分请求和命令?

最佳答案

这个过滤器还有一个问题:它的选项是在应用程序实例化时创建的,因此如果您的实体列表在应用程序运行期间发生了更改,它仍然会返回相同的选项列表。

要解决这两个问题,您不需要推迟 View 注册。您需要过滤器在每次使用时获取选项列表。

This SO answer问题“在 Python 中重置生成器对象”描述了一种重用生成器的方法(在您的情况下 - 数据库查询):

from flask import has_app_context

def get_entities():
# has_app_context is used to prevent database access
# when application is not ready yet
if has_app_context():
for entity in Entity.query.filter(Entity.active.is_(True)):
yield entity.id, entity.name

class ReloadingIterator:
def __init__(self, iterator_factory):
self.iterator_factory = iterator_factory

def __iter__(self):
return self.iterator_factory()

class MyCustomFilter(BaseSQLAFilter):
def get_options(self, view):
# This will return a generator which is
# reloaded every time it is used
return ReloadingIterator(get_entities)

问题是查询到 Entity在请求期间可以多次调用 table。所以我通常使用 Flask globals 缓存单个请求的结果:
def get_entities():
if has_app_context():
if not hasattr(g, 'entities'):
query = Entity.query.filter(Entity.active.is_(True))
g.entities = [(entity.id, entity.name) for entity in query]
for entity_id, entity_name in g.entities:
yield entity_id, entity_name

关于python - 向应用程序工厂注册 flask 管理 View 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54638047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com