2011-12-22 12 views
8

मैं विकास के लिए Bottle.py और Google App Engine के dev_appserver के साथ Jinja2 टेम्पलेट का उपयोग कर रहा हूं। मैं चाहता हूं कि टेम्पलेट्स प्रत्येक अनुरोध पर स्वचालित रूप से पुनः लोड हो जाएं (या आदर्श रूप से जब वे बदलते हैं), ताकि मुझे सर्वर को पुनरारंभ करना न पड़े।Bottle.py में Jinja2 टेम्पलेट कैशिंग अक्षम करने का सबसे अच्छा तरीका क्या है?

बोतल के दस्तावेज़ों के अनुसार, आप bottle.debug(True) पर कॉल करके टेम्पलेट कैशिंग अक्षम करने में सक्षम होना चाहिए।

जिन्जा अभी भी अपने टेम्पलेट्स को कैशिंग कर रहा है। मेरा मानना ​​है कि यह बोतल jinja2 एडाप्टर लिखा गया है (यह सिर्फ एक डिफ़ॉल्ट Jinja2 लोडर का उपयोग करता है और कई विन्यास विकल्प का पर्दाफाश नहीं करता है)।

Jinja2 Docs बाद

, मुझे लगता है कि मैं एक टेम्पलेट हर बार फिर से लोड को गति प्रदान की उम्मीद करेंगे इस कस्टम लोडर ने लिखा है, लेकिन यह काम करने के लिए या तो प्रतीत नहीं होता:

import settings 
from bottle import jinja2_template 
from bottle import Jinja2Template, template as base_template 
class AutoreloadJinja2Template(Jinja2Template): 
    def loader(self, name): 
     def uptodate(): 
      # Always reload the template if we're in DEVMODE (a boolean flag) 
      return not settings.DEVMODE 
     fname = self.search(name, self.lookup) 
     if fname: 
      with open(fname, "rb") as f: 
       source = f.read().decode(self.encoding) 
      return (source, fname, uptodate) 


template = functools.partial(base_template, 
    template_adapter=AutoreloadJinja2Template, 
    template_lookup = settings.TEMPLATE_PATHS, 
    template_settings={ 
     'auto_reload': settings.DEVMODE 
    } 
) 

टेम्पलेट्स अभी भी संचित किया जा रहा है जब तक मैं पुनः आरंभ dev_appserver। यह एक काफी आम समस्या होनी चाहिए। क्या किसी के पास कोई समाधान है जो काम करता है?

अद्यतन:

मैं की तरह कुछ कर रही समाप्त हो गया:

class CustomJinja2Template(Jinja2Template): 
    if settings.DEVMODE: 
     def prepare(self, *args, **kwargs): 
      kwargs.update({'cache_size':0}) 
      return Jinja2Template.prepare(self, *args, **kwargs) 

template = functools.partial(original_template, template_adapter=CustomJinja2Template) 

यह हमेशा फिर से लोड करने के लिए टेम्पलेट्स का कारण बनता है, लेकिन एक अजगर मॉड्यूल को छुआ कर दिया गया है केवल यदि। यानी यदि आप सिर्फ एक टेम्पलेट फ़ाइल संपादित करते हैं, तो परिवर्तन तब तक प्रभावित नहीं होंगे जब तक आप इसे आयात करने वाली पाइथन फ़ाइलों में से किसी एक को संपादित नहीं करते। ऐसा लगता है जैसे टेम्पलेट्स को अभी भी कैश किया जा रहा है।

उत्तर

6

मैंने बोतल के टेम्पलेट समाधानों को पूरी तरह से हटाकर और शुद्ध जिन्जा 2 का उपयोग करके इस मुद्दे को हल किया। ऐसा लगता है कि जिंजजा का FileSystemLoader एकमात्र ऐसा है, जो फ़ाइल परिवर्तनों के लिए देख सकता है।

from jinja2 import Environment, FileSystemLoader 

if local_settings.DEBUG: 
    jinja2_env = Environment(loader=FileSystemLoader('views/'), cache_size=0) 
else: 
    jinja2_env = Environment(loader=FileSystemLoader('views/')) 

def template(name, ctx): 
    t = jinja2_env.get_template(name) 
    return t.render(**ctx) 

तब मैं इसे इस तरह का उपयोग करें::

@route('/hello') 
def hello(): 
    return template('index.tpl', {'text': "hello"}) 

से अंतर

मैं के रूप में इस प्रकार है (यह views/ में फ़ाइलों के लिए लग रहा है, बस के लिए इस्तेमाल किया बोतल की तरह) नई template समारोह में परिभाषित किया गया बोतल की एपीआई यह है कि आपको फ़ाइल नाम में .tpl शामिल करना होगा और आपको संदर्भ चर के रूप में संदर्भ चर को पास करना होगा।

3

jinja2 में Environment वस्तु दस्तावेज़ के अनुसार कैश आकार के लिए एक विन्यास मूल्य नहीं है और,,

If the cache size is set to 0 templates are recompiled all the time

आप कुछ इस तरह की कोशिश की है?

from jinja2 import Environment 
env = Environment(cache_size=0) 
1

बोतल व्यू सजावट का उपयोग करके, आप केवल @view('your_view', cache_size=0) कर सकते हैं।

बोतल में सर्वर एडाप्टर में reloader=True पैरामीटर है, लेकिन मुझे लगता है कि यह केवल SimpleTemplate के साथ काम करता है। मैं इस व्यवहार को अन्य टेम्पलेट इंजनों में विस्तारित करने का प्रयास करूंगा। इस तरह

import functools 
view = functools.partials(view, cache_size=0) 

, आप अगर यह करने के लिए बयान एक जोड़ने यह कर सकते हैं केवल जब आप डिबग मोड में हैं:

आप अपने सभी विचारों में यह करना चाहते हैं, हो सकता है आप कुछ इस तरह कर सकते हैं कोड if bottle.DEBUG

+0

डाउनारोइंग क्योंकि cache_size = 0 तर्क दृश्य() सजावट या टेम्पलेट() फ़ंक्शन का उपयोग करके मेरे लिए काम नहीं करता है। यह भी चलाएं (पुनः लोडर = ट्रू) एक त्रुटि फेंकता है: "स्थानीय चर 'लॉकफाइल' असाइनमेंट से पहले संदर्भित" – arkanciscan

+0

@arkanciscan यह बग शायद यह मेरे प्रतिक्रियाक से संबंधित नहीं है, लेकिन यह ठीक है। बस आपको पता है, मैंने बोतल को एक समस्या के रूप में आपकी टिप्पणी की सूचना दी है (https://github.com/defnull/bottle/issues/278)। क्या आप जिथब में बग के बारे में अधिक जानकारी दे सकते हैं? आप किस सर्वर एडाप्टर का उपयोग कर रहे हैं? धन्यवाद! बग रिपोर्ट के लिए – iurisilvio

+0

+1, धन्यवाद :) – defnull

5

बोतल कैश टेम्पलेट आंतरिक रूप से (Jinja2 कैशिंग से स्वतंत्र)। आप bottle.debug(True) या bottle.run(..., debug=True) के माध्यम से कैश को अक्षम कर सकते हैं या bottle.TEMPLATES.clear() के साथ कैश साफ़ कर सकते हैं।

+0

प्रतिक्रिया के लिए धन्यवाद। मुझे बोतल के बारे में पता नहीं था। टेम्पलेट्स.क्लर(), जो काम में आ सकता है! मेरे पास प्रोजेक्ट की शुरुआत से बोतल.डेबग (ट्रू) सेट है, इसलिए मुझे पूरा यकीन है कि यह जिन्जा के कैश को कॉन्फ़िगर करने में एक समस्या है। – leted

+0

मुझे क्या ट्रिप किया गया है बोतल.बुन से पहले बोतल.डेबग (ट्रू) चल रहा है। bottle.run के डीबग तर्क में गलत का डिफ़ॉल्ट मान होता है जो निर्दिष्ट नहीं होने पर बोतल को ओवरराइट करता है .DEBUG। –