سؤال

تطبيقي يعمل على محرك التطبيق ويتم تطبيقه باستخدام Werkzeug. و jinja2.. وبعد أود الحصول على شيء ما يعادله بشكل وظيفي معالج سياق Django الخاص به: استدعاء يستغرق طلبا ويضيف شيئا إلى سياق القالب. لدي بالفعل "معالجات السياق" التي تضيف شيئا إلى سياق القالب، ولكن كيف يمكنني الحصول على هذا طلب جزء العمل؟ لقد قمت بتنفيذ معالجات السياق كقليل لاستخدام القاموس الذي يستخدمه في وقت لاحق لتحديث السياق.

على سبيل المثال، أود أن أضيف شيئا واحدا request.environ.

هل كانت مفيدة؟

المحلول

طريقة واحدة لتحقيق هذا هو من خلال المتأخر قالب globals. باستخدام الوكيل المحلي للخيط في Werkzeug.

مثال بسيط يضع الطلب في Globals القالب:

from werkzeug import Local, LocalManager
local = Local()
local_manager = LocalManager([local])

from jinja2 import Environment, FileSystemLoader

# Create a global dict using the local's proxy to the request attribute
global_dict = {'request': local('request')}
jinja2_env = Environment(loader=FileSystemLoader('/'))
jinja2_env.globals.update(global_dict)

def application(environ, start_response):
    """A WSGI Application"""
    # later, bind the actual attribute to the local object
    local.request = request = Request(environ)

    # continue to view handling code
    # ...

application = local_manager.make_middleware(application)

الآن في أي من القوالب الخاصة بك، ستظهر الطلب الحالي مرتبطا بالمتغير "الطلب". بالطبع يمكن أن يكون أي شيء آخر في البيئة. الحيلة هي استخدام الوكيل المحلي، ثم قم بتعيين القيمة قبل تقديم أي قالب.

ربما يجب أن أضيف أيضا إلى هذا الإطار مثل glashammer. (Werkzeug + Jinja2) تقوم بتبسيط هذه العملية لك باستخدام الأحداث. يمكن أن تتصل العديد من الوظائف بالأحداث أثناء عملية مكالمة WSGI (على سبيل المثال، عند إنشاء طلب) ويمكنهم وضع الأشياء في مساحة اسم القالب في تلك المرحلة.

نصائح أخرى

حسنا، باستخدام ما كتب علي جئت إلى الحل الخاص بمحرك التطبيق (بسبب ذاكرة التخزين المؤقت للاستيراد). لسوء الحظ، لا يعمل رمز ALI مع محرك التطبيق، لأن التعليمات البرمجية التي يحدد Jinja Globals يتم استيرادها مرة واحدة فقط (جعل Globals ثابتة ثابتة).

اضطررت إلى كتابة بلدي render() وظيفة وتحديث السياق هناك. من أجل اكتمال، أدناه هو الرمز الذي جئت إليه:

def render(template, **kwargs):
    response_code = kwargs.pop('response_code', 200)
    mimetype = kwargs.pop('mimetype', 'text/html')
    for item in getattr(settings, 'CONTEXT_PROCESSORS', []):
        try:
            processor = import_string(item)
            kwargs.update(processor(local.request))
        except (ImportError, AttributeError), e:
            logging.error(e)
    return Response(jinja_env.get_template(template).render(**kwargs),
        status=response_code, mimetype=mimetype)

هذا هو محرك التطبيق محددة. في بيئات أخرى تعمل رمز ALI كما هو متوقع (وهذا هو السبب في أنني أقوم بإعادة تقييم سؤالي).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top