Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
URL Converters should have access to app context #3088
The following code should create a new URL converter that converts a specific field to a model (or
class ModelConverter(BaseConverter): def to_python(self, value): return models.Example.query.filter(models.Example.name == value).first() def to_url(self, value): if isinstance(value, str): return value return value.name
The converters don't have access to the app context so an error is thrown.
class OrganizationConverter(BaseConverter): app = None def to_python(self, value): with self.app.app_context(): return repositories.Organization.query.filter(repositories.Organization.name == value).first() def to_url(self, value): if isinstance(value, str): return value return value.name
This solution tries to get around it by creating a new app context. The problem is that the context disappears, killing the database session at the same time. This prevents SQLAlchemy features (such as lazy loading).
This issue has also come up on stack overflow
I've also ran into this issue with converters, but it's might not be straightforward to change at this point.
URL matching is done as part of creating the request context, not pushing the context:
So we'd need to move it into
It's a more internal part of Flask, and I haven't really seen any discussion about overriding or using these parts, but I'd have to understand that more before making the change.
ok sorry, a question before I add the PR.
def test_model_converters(app, client): from werkzeug.routing import BaseConverter app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' db = SQLAlchemy(app) class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) db.create_all() admin = User(username='admin', firstname.lastname@example.org') db.session.add(admin) class ModelConverter(BaseConverter): def to_python(self, value): return User.query.filter(User.username == value).first() def to_url(self, value): if isinstance(value, str): return value return value.username app.url_map.converters['model'] = ModelConverter @app.route('/<model:user_name>') def index(user_name): return user_name.email assert client.get('/admin').data == email@example.com'
However, I did not get the out of context exception, what am I missing here?