如何从烧瓶中的方法路由中访问ContextH_Processor?

发布于 2025-01-27 21:35:24 字数 648 浏览 5 评论 0原文

我想设置我的视图和方法可用的变量,而不会污染fore_request装饰器中的请求对象。

上下文处理器似乎是一种很好的方法,但是,我不知道如何从我的方法中实际访问它们。

我提出的最好的解决方案是记忆上下文函数,以便在我的方法中一次不会被我调用两次,然后再一次将烧瓶注入模板中。

但是,这将缓解所有将来请求的方法,我只希望根据请求缓存它。

这是我的工作示例,

from functools import cache

@app.context_processor
@cache
def setup_context():
  return {
    'planet': db.query('select planet from planets order by random()').first() 
  }

@app.route("/")
def index():
   ctx = setup_context()
   if ctx['planet'] == 'pluto':
      return redirect('/pluto-is-not-a-planet')
   return render_template('planet_greeting.html')
   

关于如何在不使用functools.cache的情况下完成此操作的任何想法?

I'd like to setup variables available to both my views and my methods without polluting the request object in a before_request decorator.

Context processors seems like a nice way to do this however, I can't figure out how to actually access them from within my methods.

The best solution I have come up with is to memoize the context function so that it doesn't get called twice, once by me in my method and then again when Flask injects it into the template.

However, this will cache the method for all future requests and I only want it cached per request.

Here is my working example

from functools import cache

@app.context_processor
@cache
def setup_context():
  return {
    'planet': db.query('select planet from planets order by random()').first() 
  }

@app.route("/")
def index():
   ctx = setup_context()
   if ctx['planet'] == 'pluto':
      return redirect('/pluto-is-not-a-planet')
   return render_template('planet_greeting.html')
   

Any ideas on how to accomplish this without using functools.cache?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

巨坚强 2025-02-03 21:35:24

可能有一种更优雅的方式来做到这一点,但这是我到目前为止提出的。

基本思想是使用扩展模式并创建应用程序传递给对象“当前”。

然后,我可以使用此对象上的属性访问_app_ctx_stack以及使用Context_Processor Hook的上下文变量填充模板。

这种方法将使我拥有不使用“ G”的模板,并且可以在路线上使用的一个不错的对象。

from flask import (
    Flask, current_app, _app_ctx_stack,
    render_template as template
)
from random import shuffle

planets = ['earth', 'pluto', 'mars']

class Current(object):
    def __init__(self, app=None):
        self.app = app
        self.app.context_processor(self.context_processor)
        
    def context_processor(self):
        return _app_ctx_stack.top.__dict__

    @property
    def planet(self):
        ctx = _app_ctx_stack.top
        if not hasattr(ctx, 'planet'):
            shuffle(planets)
            ctx.planet = {
                'name': planets[0]
            }
        return ctx.planet

app = Flask(__name__)
current = Current(app)

@app.route("/")
def index():
    if current.planet['name'] == 'pluto':
        return "Pluto is not a planet!"

    return template("planet.html")
    
if __name__ == '__main__':
    app.run(debug=True)

在我的模板中

{%# in my template %}
The planet is {{ planet.name }}!

There may be a more elegant way to do this but here is what I have come up with so far.

The basic idea is to use the extensions pattern and create an object "Current" that the app gets passed to.

I can then use properties on this object to access the _app_ctx_stack as well as populate templates with context variables using the context_processor hook.

This approach will allow me to have templates that don't use "g" and a nice object to work with in my routes.

from flask import (
    Flask, current_app, _app_ctx_stack,
    render_template as template
)
from random import shuffle

planets = ['earth', 'pluto', 'mars']

class Current(object):
    def __init__(self, app=None):
        self.app = app
        self.app.context_processor(self.context_processor)
        
    def context_processor(self):
        return _app_ctx_stack.top.__dict__

    @property
    def planet(self):
        ctx = _app_ctx_stack.top
        if not hasattr(ctx, 'planet'):
            shuffle(planets)
            ctx.planet = {
                'name': planets[0]
            }
        return ctx.planet

app = Flask(__name__)
current = Current(app)

@app.route("/")
def index():
    if current.planet['name'] == 'pluto':
        return "Pluto is not a planet!"

    return template("planet.html")
    
if __name__ == '__main__':
    app.run(debug=True)

And in my template

{%# in my template %}
The planet is {{ planet.name }}!
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文