I used Turbogears 2.3.11. I have 1 application and 2 Pluggable Applications with TurboGears. In Pluggable Applications have own models. How to call model in one Pluggable Application from two Pluggable Application?
In example:
- mainapp
-- model
--- __init__.py
--- auth.py
- plugapp_one
-- model
--- __init__.py
--- models.py
---- Book
- plugapp_two
-- model
--- __init__.py
--- models.py
---- Buyer
---- Card
In Card Object call relation to Book Object, I use app_model.Book. It error
AttributeError: 'module' object has no attribute 'Book'
My Code in models.py of plugapp_two
from tgext.pluggable import app_model, primary_key
class Card(DeclarativeBase):
__tablename__ = 'card'
uid = Column(Integer, autoincrement=True, primary_key=True)
name = Column(Unicode(16))
id_book = Column(Integer, ForeignKey(primary_key(app_model.Book)))
book = relation(app_model.Book)
You have two choices:
Explicitly provide the Model at plug time, usually in the form like
package.module:Model. Much like tgapp-resetpassword does for its forms: https://github.com/axant/tgapp-resetpassword#plugin-options. Then wherever you need to access that model you access the one specified there. The hard part is that you must ensure that every place that accesses that Model accesses it lazily, or you might end up trying to use it before it was configured. SeeLazyForeignKeyhttps://github.com/TurboGears/tgext.pluggable#relations-with-plugged-apps-modelsOption 1 is surely the most flexible as you choose which model is related at plugin time, but in case you are using pluggable apps just to split your own application and don't plan to reuse them you can just plug them all with
global_models=Trueoption and all the models from the pluggable apps will end up being available intgext.pluggable.app_model.Model.Note that both solution need to pay attention to when you access the model, as it might have not been plugged yet. You should try to delay model usage as much as possible through
LazyForeignKeyandrelationshipwith lambdas, such that the model is only used when actually needed. Or you might end up trying to access it before it was plugged.