Tải lại ứng dụng Flask khi tệp mẫu thay đổi


95

Theo mặc định, khi chạy ứng dụng Flask bằng máy chủ tích hợp ( Flask.run), nó sẽ giám sát các tệp Python của nó và tự động tải lại ứng dụng nếu mã của nó thay đổi:

* Detected change in '/home/xion/hello-world/app.py', reloading
* Restarting with reloader

Thật không may, điều này dường như chỉ hoạt động với các tệp * .py và dường như tôi không tìm thấy bất kỳ cách nào để mở rộng chức năng này cho các tệp khác. Đáng chú ý nhất, sẽ cực kỳ hữu ích nếu Flask khởi động lại ứng dụng khi một mẫu thay đổi. Tôi đã không còn đếm được bao nhiêu lần tôi loay hoay với việc đánh dấu trong các mẫu và bối rối khi không thấy bất kỳ thay đổi nào, chỉ khi phát hiện ra rằng ứng dụng vẫn đang sử dụng phiên bản cũ của mẫu Jinja.

Vì vậy, có cách nào để có các tệp giám sát Flask trong thư mục mẫu , hay nó yêu cầu tìm hiểu sâu về nguồn của khung công tác?

Chỉnh sửa : Tôi đang sử dụng Ubuntu 10.10. Thực sự chưa thử điều đó trên bất kỳ nền tảng nào khác.


Sau khi tìm hiểu thêm, tôi đã phát hiện ra rằng các thay đổi trong mẫu thực sự được cập nhật theo thời gian thực mà không cần tải lại ứng dụng. Tuy nhiên, điều này dường như chỉ áp dụng cho những mẫu được chuyển đến flask.render_template.

Nhưng điều đó xảy ra là trong ứng dụng của tôi, tôi có khá nhiều thành phần có thể tái sử dụng, được tham số hóa mà tôi sử dụng trong các mẫu Jinja. Chúng được triển khai dưới dạng {% macro %}s, nằm trong "mô-đun" chuyên dụng và được chỉnh sửa {% import %}thành các trang thực tế. Tất cả đều đẹp và KHÔ ... ngoại trừ việc các mẫu đã nhập đó dường như không bao giờ được kiểm tra để sửa đổi, vì chúng hoàn toàn không được thông qua render_template.

(Thật kỳ lạ, điều này không xảy ra đối với các mẫu được gọi qua {% extends %}. Về phần {% include %}, tôi không biết vì tôi không thực sự sử dụng chúng.)

Vì vậy, để tóm lại, gốc rễ của hiện tượng này dường như nằm ở đâu đó giữa Jinja và Flask hoặc Werkzeug. Tôi đoán nó có thể đảm bảo một chuyến đi đến trình theo dõi lỗi cho một trong hai dự án đó :) Trong khi đó, tôi đã chấp nhận jd. Câu trả lời là vì đó là giải pháp mà tôi thực sự đã sử dụng - và nó hoạt động như một sự quyến rũ.


3
Đảm bảo rằng ứng dụng được định cấu hình với DEBUG = True, hãy xem tài liệu .
Alex Morega

Câu trả lời:


65

Theo kinh nghiệm của tôi, các mẫu thậm chí không cần ứng dụng khởi động lại để được làm mới, vì chúng sẽ được tải từ đĩa mỗi khi render_template()được gọi. Có thể các mẫu của bạn được sử dụng khác nhau.

Để tải lại ứng dụng của bạn khi các mẫu thay đổi (hoặc bất kỳ tệp nào khác), bạn có thể chuyển extra_filesđối số tới Flask().run(), một tập hợp các tên tệp để xem: bất kỳ thay đổi nào trên các tệp đó sẽ kích hoạt trình tải lại.

Thí dụ:

from os import path, walk

extra_dirs = ['directory/to/watch',]
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
    for dirname, dirs, files in walk(extra_dir):
        for filename in files:
            filename = path.join(dirname, filename)
            if path.isfile(filename):
                extra_files.append(filename)
app.run(extra_files=extra_files)

Xem tại đây: http://werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple


Đồ tốt! Tôi thừa nhận rằng tôi đã bỏ lỡ liên kết trong tài liệu Flask.rundẫn đến tài liệu Werkzeug. Nhưng tùy chọn cụ thể này có vẻ đủ hữu ích để ít nhất nó đã được đề cập trong tài liệu về Flask.
Xion

Nếu bất cứ ai gặp một lỗi mà nói No such file or directory, hãy thử sử dụng đường dẫn tương đối như trong:extra_dirs = ['./directory/to/watch',]
Kevin

3
Nếu bạn quá bối rối về những gì pathlà, đó là os.path. nghĩ rằng điều đó là đáng nói
bjesus

Để tự động tải lại sau khi thay đổi tệp tĩnh, hãy xem phần này .
simanacci

1
Bất kỳ ý tưởng nào về cách chỉ định các tệp bổ sung khi chạy flask runtừ dòng lệnh?
Michael Scheper

143

bạn có thể dùng

TEMPLATES_AUTO_RELOAD = True

Từ http://flask.pocoo.org/docs/1.0/config/

Có kiểm tra các sửa đổi của nguồn mẫu và tải lại tự động hay không. Theo mặc định, giá trị là Không có nghĩa là Flask chỉ kiểm tra tệp gốc ở chế độ gỡ lỗi.


11
Giải pháp này là thông thường, được hỗ trợ bởi tài liệu, đơn giản để hiểu và dễ thực hiện. Nó nên được chấp nhận!
Carolyn Conway

Tôi cố gắng trả lời này, nhưng chỉ có tác dụng một lần, sau khi làm mới khác nó sẽ không làm việc
medev21

3
Chỉ là một lưu ý cho những người khác: Tôi đã làm app.config['TEMPLATES_AUTO_RELOAD'] = True, và vì một số lý do, dự kiến ​​sẽ thấy máy chủ tự động khởi động lại khi một mẫu thay đổi, giống như ở chế độ gỡ lỗi. Nó không khởi động lại, nhưng nó KHÔNG cập nhật mẫu mà nó hiển thị.
cs01

3
Bất kỳ lý do nào tại sao điều này sẽ không hoạt động cho 0,12? hoặc một số cài đặt khác có thể ngăn không cho cài đặt này đúng?
user805981

3
@Federer Có vẻ như nó không hoạt động như trước đây ... Trước đây, nó đã phát hiện những thay đổi trong thư mục mẫu và các thư mục con và nó sẽ tải lại máy chủ .... Đây có phải là điều mới trong 0.12 đó không đã thay đổi?
user805981 Ngày

54

Khi bạn đang làm việc với các jinjamẫu, bạn cần thiết lập một số tham số. Trong trường hợp của tôi với python3, tôi đã giải quyết nó bằng mã sau:

if __name__ == '__main__':
    app.jinja_env.auto_reload = True
    app.config['TEMPLATES_AUTO_RELOAD'] = True
    app.run(debug=True, host='0.0.0.0')

1
Bạn đã cứu sự tỉnh táo của tôi. Cảm ơn bạn.
Nostalg.io

Tôi cũng đang gặp khó khăn với vấn đề đó. Tôi rất vui vì tôi có thể giúp;)
silgon

Điều này đang hoạt động đối với tôi trên flask 1.0.2, nhưng tôi không có đối số máy chủ.
Enrico Borba

Vâng @EnricoBorba, bạn có thể sẽ không cần nó. Tôi thường sử dụng nó vì tôi gỡ lỗi cục bộ bằng docker và đôi khi ứng dụng cần được truy cập từ một vùng chứa khác. Một số tài liệu tham khảo
silgon

@silgon Vâng, tôi hiểu. Tôi chủ yếu chỉ làm tăng thêm bình luận được rõ ràng về những gì đã làm việc trên một tươi cài đặt của Flask phiên bản 1.0.2
Enrico Borba


10

Trên thực tế đối với tôi TEMPLATES_AUTO_RELOAD = Truekhông hoạt động (phiên bản 0.12). Tôi sử dụng jinja2 và những gì tôi đã làm:

  1. Tạo chức năng before_request

    def before_request():
        app.jinja_env.cache = {}
  2. Đăng ký nó trong ứng dụng

    app.before_request(before_request)
  3. Đó là nó.


3
Garret, tôi đã không thử nghiệm nếu không có các tùy chọn này.
dikkini

Bước 3 không thực sự cần thiết, nó hoạt động rất tốt với tôi.
Ricardo Ribeiro

4

Những gì làm việc cho tôi chỉ là thêm điều này:

@app.before_request
def before_request():
    # When you import jinja2 macros, they get cached which is annoying for local
    # development, so wipe the cache every request.
    if 'localhost' in request.host_url or '0.0.0.0' in request.host_url:
        app.jinja_env.cache = {}

( trích từ câu trả lời của @ dikkini )


2

Sử dụng phiên bản Flask mới nhất trên Windows, sử dụng lệnh chạy và gỡ lỗi được đặt thành true; Không cần đặt lại bình để các thay đổi đối với mẫu có hiệu lực. Hãy thử Shift + F5 (hoặc Shift cộng với nút tải lại) để đảm bảo không có gì trong bộ nhớ cache.



1

Cập nhật vào tháng 6 năm 2019:

Các CLI bình được khuyến khích hơn app.run () để chạy một máy chủ dev, vì vậy nếu chúng ta muốn sử dụng CLI thì giải pháp chấp nhận không thể được sử dụng.

Việc sử dụng phiên bản phát triển của Flask (1.1) kể từ lần viết này cho phép chúng tôi thiết lập một biến môi trường FLASK_RUN_EXTRA_FILES thực hiện hiệu quả điều tương tự như câu trả lời được chấp nhận.

Xem vấn đề github này .

Ví dụ sử dụng:

export FLASK_RUN_EXTRA_FILES="app/templates/index.html"
flask run

trong Linux. Để chỉ định nhiều tệp bổ sung, hãy tách các đường dẫn tệp bằng dấu hai chấm. , ví dụ

export FLASK_RUN_EXTRA_FILES="app/templates/index.html:app/templates/other.html"

CLI cũng hỗ trợ một --extra-filesđối số như Flask 1.1.


cập nhật nhỏ. liên kết đến 'flask CLI' cần cập nhật lên phiên bản hiện tại. flask.palletsprojects.com/en/1.1.x/cli nếu không thì cảm ơn :)
CodingMatters

1

Các mẫu được tải lại tự động, tại sao không làm ctrl+f5để làm mới trang web, vì trình duyệt web thường tiết kiệm bộ nhớ cache.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.