Kar*_*bet 9 python sqlalchemy flask flask-admin
据我所知,Flask Admin支持AJAX用于外键模型加载.该瓶管理员-模型文档覆盖标题下的基本知识form_ajax_refs
.我已成功地在很多场合成功使用它,但是我希望实现自定义级别的问题.让我详细说明一下.
我有一个Product
模型,一个Organisation
模型和一个连接表来关联它们,定义如下:
class Product(Base):
__tablename__ = "products"
product_uuid = Column(UUID(as_uuid=True), primary_key=True)
title = Column(String, nullable=False)
description = Column(String, nullable=False)
last_seen = Column(DateTime(timezone=True), nullable=False, index=True)
price = Column(Numeric(precision=7, scale=2), nullable=False, index=True)
class Organisation(Base):
__tablename__ = "organisations"
org_id = Column(String, primary_key=True)
org_name = Column(String, nullable=False)
products = relationship(
Product,
secondary="organisation_products",
backref="organisations"
)
organisation_products_table = Table(
"organisation_products",
Base.metadata,
Column("org_id", String, ForeignKey("organisations.org_id"), nullable=False),
Column("product_uuid", UUID(as_uuid=True), ForeignKey("products.product_uuid"), nullable=False),
UniqueConstraint("org_id", "product_uuid"),
)
Run Code Online (Sandbox Code Playgroud)
在名为模型的Flask管理模型视图中,该模型CuratedList
具有模型的外键约束Product
,我form_ajax_refs
在表单创建视图中使用,以允许选择动态加载的Product
项目.
form_ajax_refs = {"products": {"fields": (Product.title,)}}
Run Code Online (Sandbox Code Playgroud)
这很好地向我展示了Product
模型的所有行.
但是,我目前的要求是仅使用AJAX模型加载器来显示具有特定org_id的产品,例如"Google".
覆盖要加入和过滤get_query
的ModelView
类的功能.这看起来像这样:organisation_products_table
org_id
def get_query(self):
return (
self.session.query(CuratedList)
.join(
curated_list_items_table,
curated_list_items_table.c.list_uuid == CuratedList.list_uuid
)
.join(
Product,
Product.product_uuid == curated_list_items_table.c.product_uuid
)
.join(
organisation_products_table,
organisation_products_table.c.product_uuid == Product.product_uuid
)
.filter(CuratedList.org_id == "Google")
.filter(organisation_products_table.c.org_id == "Google")
)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这并没有解决问题,并返回相同的行为:
def get_query(self):
return (
self.session.query(CuratedList)
.filter(CuratedList.org_id == self._org_id)
)
Run Code Online (Sandbox Code Playgroud)
它不会影响行为form_ajax_refs
.
该瓶管理员-模型文档提及使用的另一种方法form_ajax_refs
,使用涉及QueryAjaxModelLoader
类.
在我的第二次尝试,我继承的QueryAjaxModelLoader
类,并试图覆盖值的是model
,session
或fields
变量.像这样的东西:
class ProductAjaxModelLoader(QueryAjaxModelLoader):
def __init__(self, name, session, model, **options):
super(ProductAjaxModelLoader, self).__init__(name, session, model, **options)
fields = (
session.query(model.title)
.join(organisation_products_table)
.filter(organisation_products_table.c.org_id == "Google")
).all()
self.fields = fields
self.model = model
self.session = session
Run Code Online (Sandbox Code Playgroud)
然后,而不是以前的form_ajax_refs
方法,我AjaxModelLoader
像这样使用我的新:
form_ajax_refs = {
"products": ProductAjaxModelLoader(
"products", db.session, Product, fields=['title']
)
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,无论是覆盖我的查询的值session
还是model
我的查询的值都不会返回AJAX加载器中的产品,并且覆盖fields
仍会返回所有产品; 不只是org_id"Google"的产品.
我希望能够在不必为每个组织创建新模型的情况下实现这一点,因为这将证明是不可扩展的并且设计不好.
欢迎任何建议.谢谢.
感谢Joes对我原来的问题的评论,我已经制定了一个有效的解决方案:
像这样覆盖AjaxModelLoader
函数get_list
:
def get_list(self, term, offset=0, limit=DEFAULT_PAGE_SIZE):
filters = list(
field.ilike(u'%%%s%%' % term) for field in self._cached_fields
)
filters.append(Organisation.org_id == "Google")
return (
db.session.query(Product)
.join(organisation_products_table)
.join(Organisation)
.filter(*filters)
.all()
)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3225 次 |
最近记录: |