2011-12-22 35 views
8

Tôi đang sử dụng các mẫu Jinja2 với Bottle.py và dev_appserver của Google App Engine để phát triển. Tôi muốn các mẫu tự động tải lại trên mọi yêu cầu (hoặc lý tưởng chỉ khi chúng thay đổi), do đó tôi không phải tiếp tục khởi động lại máy chủ.Cách tốt nhất để vô hiệu hóa bộ đệm mẫu Jinja2 trong bottle.py là gì?

Theo tài liệu của chai, bạn có nghĩa vụ có thể vô hiệu hóa bộ nhớ cache mẫu bằng cách gọi bottle.debug(True).

Tuy nhiên, dường như Jinja vẫn đang lưu vào bộ nhớ cache mẫu của nó. Tôi tin rằng điều này là do cách các jinja2 chai adapter được viết (nó chỉ sử dụng một bộ nạp Jinja2 mặc định và không lộ nhiều tùy chọn cấu hình).

Tiếp theo Jinja2 Docs, tôi đã viết này Loader tùy chỉnh mà tôi mong chờ để kích hoạt một mẫu reload mọi thời gian, nhưng nó dường như không làm việc, hoặc:

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 
    } 
) 

Templates vẫn bị lưu trữ cho đến khi tôi khởi động lại dev_appserver. Đây phải là một vấn đề khá phổ biến. Có ai có một giải pháp hoạt động?

UPDATE:

tôi đã kết thúc làm một cái gì đó như:

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) 

Điều này làm cho các mẫu để luôn tải lại, nhưng chỉ khi một module trăn đã được chạm vào. tức là nếu bạn chỉ chỉnh sửa tệp mẫu, các thay đổi sẽ không có hiệu lực cho đến khi bạn chỉnh sửa một trong các tệp python nhập tệp đó. Dường như các mẫu vẫn đang được lưu trữ ở đâu đó.

Trả lời

6

Tôi đã giải quyết vấn đề này bằng cách bỏ hoàn toàn các giải pháp mẫu của chai và sử dụng jinja2 tinh khiết. Có vẻ như chỉ FileSystemLoader của Jijnja là người duy nhất có thể xem các thay đổi của tệp.

tôi xác định template chức năng mới như sau (nó sẽ tìm kiếm tập tin trong views/, giống như chai dùng để):

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) 

Sau đó, tôi sử dụng nó như thế này:

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

Sự khác biệt từ API của chai là bạn phải bao gồm .tpl trong tên tệp và bạn phải chuyển các biến ngữ cảnh làm từ điển.

3

Đối tượng Environment trong jinja2 có giá trị cấu hình cho kích thước bộ nhớ cache và, theo các tài liệu,

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

Các bạn đã thử một cái gì đó như thế này?

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

Sử dụng trình xem trang trí chai, bạn chỉ có thể thực hiện @view('your_view', cache_size=0).

Chai có thông số reloader=True trong bộ điều hợp máy chủ, nhưng tôi đoán nó chỉ hoạt động với SimpleTemplate. Tôi sẽ cố gắng mở rộng hành vi này cho các công cụ mẫu khác.

Nếu bạn muốn làm điều đó trong tất cả các quan điểm của bạn, có lẽ bạn có thể làm một cái gì đó như thế này:

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

Bằng cách này, bạn có thể làm điều đó chỉ khi bạn đang ở trong chế độ gỡ lỗi thêm một câu lệnh if này mã số if bottle.DEBUG.

+0

Downarrowing vì đối số cache_size = 0 không hoạt động đối với tôi bằng cách sử dụng trình trang trí view() hoặc hàm template(). Cũng chạy (reloader = True) ném một lỗi: "local variable 'lockfile' được tham chiếu trước khi gán" – arkanciscan

+0

@arkanciscan bug này có lẽ nó không liên quan đến responseq của tôi, nhưng nó vẫn ổn. Chỉ cần cho bạn biết, tôi báo cáo bình luận của bạn là một vấn đề để chai (https://github.com/defnull/bottle/issues/278). Bạn có thể cung cấp thêm chi tiết về lỗi trong github không? Bạn đang sử dụng bộ điều hợp máy chủ nào? Cảm ơn! – iurisilvio

+0

+1 cho báo cáo lỗi, cảm ơn :) – defnull

5

Mẫu cache lưu trữ nội bộ (độc lập với bộ nhớ đệm Jinja2). Bạn có thể tắt bộ nhớ cache qua bottle.debug(True) hoặc bottle.run(..., debug=True) hoặc xóa bộ nhớ cache với bottle.TEMPLATES.clear().

+0

Cảm ơn bạn đã phản hồi. Tôi không biết về chai.TEMPLATES.clear(), có thể có ích! Tôi đã có chai.debug (True) được đặt từ đầu dự án, vì vậy tôi chắc chắn đó là vấn đề cấu hình bộ nhớ cache của Jinja. – leted

+0

Những gì tôi vấp phải là chạy bottle.debug (True) trước khi chai.run. đối số gỡ lỗi của bottle.run có giá trị mặc định là False sẽ ghi đè lên chai.DEBUG nếu không được chỉ định. –

Các vấn đề liên quan