โหลดแอพ Flask ใหม่เมื่อไฟล์เทมเพลตเปลี่ยน


96

โดยค่าเริ่มต้นเมื่อเรียกใช้แอปพลิเคชัน Flask โดยใช้เซิร์ฟเวอร์ในตัว ( Flask.run) จะตรวจสอบไฟล์ Python และโหลดแอปซ้ำโดยอัตโนมัติหากรหัสเปลี่ยนแปลง:

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

น่าเสียดายที่ดูเหมือนว่าจะใช้ได้กับไฟล์* .pyเท่านั้นและดูเหมือนว่าฉันจะไม่พบวิธีใดในการขยายฟังก์ชันนี้ไปยังไฟล์อื่น ๆ ที่สำคัญที่สุดคือการให้ Flask รีสตาร์ทแอปเมื่อเทมเพลตเปลี่ยนไปจะมีประโยชน์อย่างยิ่ง ฉันนับไม่ได้ว่ากี่ครั้งแล้วที่ฉันเล่นซอกับมาร์กอัปในเทมเพลตและสับสนโดยไม่เห็นการเปลี่ยนแปลงใด ๆ เพียงเพื่อจะพบว่าแอปยังคงใช้เทมเพลต Jinja เวอร์ชันเก่าอยู่

ดังนั้นมีวิธีใดบ้างที่จะมีไฟล์มอนิเตอร์ Flask ในไดเร็กทอรีtemplateหรือไม่หรือต้องดำน้ำในซอร์สของเฟรมเวิร์ก

แก้ไข : ฉันใช้ Ubuntu 10.10 ยังไม่ได้ลองใช้บนแพลตฟอร์มอื่นจริงๆ


หลังจากสอบถามเพิ่มเติมฉันพบว่าการเปลี่ยนแปลงในเทมเพลตได้รับการอัปเดตตามเวลาจริงโดยไม่ต้องโหลดแอปซ้ำ อย่างไรก็ตามดูเหมือนว่าจะใช้กับเทมเพลตที่ส่งผ่านไปflask.render_templateเท่านั้น

แต่มันก็เกิดขึ้นที่ในแอพของฉันฉันมีส่วนประกอบที่ใช้ซ้ำได้จำนวนมากซึ่งฉันใช้ในเทมเพลต Jinja มีการใช้งานเป็น{% macro %}s โดยอาศัยอยู่ใน "โมดูล" เฉพาะและได้รับการ{% import %}แก้ไขในหน้าเว็บจริง ทุกอย่างดูดีและแห้ง ... ยกเว้นว่าแม่แบบที่นำเข้าเหล่านั้นไม่เคยตรวจสอบการแก้ไขเนื่องจากไม่ผ่านrender_templateเลย

(อยากรู้อยากเห็นสิ่งนี้ไม่เกิดขึ้นกับเทมเพลตที่เรียกผ่าน{% extends %}ส่วน{% include %}ฉันไม่รู้เพราะฉันไม่ได้ใช้มันจริงๆ)

ดังนั้นเพื่อสรุปรากเหง้าของปรากฏการณ์นี้ดูเหมือนจะอยู่ที่ไหนสักแห่งระหว่าง Jinja และ Flask หรือ Werkzeug ฉันเดาว่าอาจรับประกันการเดินทางไปยังตัวติดตามข้อผิดพลาดสำหรับโครงการเหล่านั้น :) ในขณะเดียวกันฉันยอมรับjd คำตอบเพราะนั่นเป็นวิธีแก้ปัญหาที่ฉันใช้จริง - และมันก็ใช้ได้เหมือนมีเสน่ห์


3
ตรวจสอบให้แน่ใจแอปกำหนดค่าด้วย DEBUG = True ดูเอกสาร
Alex Morega

คำตอบ:


67

จากประสบการณ์ของฉันเทมเพลตไม่จำเป็นต้องให้แอปพลิเคชันรีสตาร์ทเพื่อรีเฟรชเนื่องจากควรโหลดจากดิสก์ทุกครั้งที่render_template()เรียก บางทีแม่แบบของคุณอาจจะใช้ไม่เหมือนกัน

ในการโหลดแอปพลิเคชันของคุณซ้ำเมื่อเทมเพลตเปลี่ยน (หรือไฟล์อื่น ๆ ) คุณสามารถส่งextra_filesอาร์กิวเมนต์ไปยังFlask().run()คอลเล็กชันชื่อไฟล์ที่จะดูได้การเปลี่ยนแปลงใด ๆ ในไฟล์เหล่านั้นจะทริกเกอร์ตัวโหลดซ้ำ

ตัวอย่าง:

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)

ดูที่นี่: http://werkzeug.pocoo.org/docs/0.10/serves/?highlight=run_simple#werkzeug.serves.run_simple


สิ่งที่ดี! ฉันยอมรับว่าฉันพลาดลิงก์ในเอกสารFlask.runที่นำไปสู่เอกสาร Werkzeug แต่ตัวเลือกนี้ดูเหมือนมีประโยชน์มากพอที่อย่างน้อยก็มีการกล่าวถึงใน Flask docs
Xion

หากใครพบข้อผิดพลาดที่ระบุNo such file or directoryให้ลองใช้เส้นทางสัมพัทธ์ดังใน:extra_dirs = ['./directory/to/watch',]
Kevin

3
หากคุณสับสนเกินไปว่าpathมันคือos.pathอะไร คิดว่าคุ้มค่าที่จะกล่าวถึง
bjesus

สำหรับรถยนต์โหลดหลังจากเปลี่ยนไฟล์คงเห็นนี้
simanacci

1
มีความคิดอย่างไรในการระบุไฟล์พิเศษเมื่อเรียกใช้flask runจากบรรทัดคำสั่ง?
Michael Scheper

147

คุณสามารถใช้ได้

TEMPLATES_AUTO_RELOAD = True

จากhttp://flask.pocoo.org/docs/1.0/config/

ตรวจสอบการแก้ไขแหล่งที่มาของเทมเพลตหรือไม่และโหลดซ้ำโดยอัตโนมัติ ตามค่าเริ่มต้นค่าจะเป็นไม่มีซึ่งหมายความว่า Flask ตรวจสอบไฟล์ต้นฉบับในโหมดดีบักเท่านั้น


11
โซลูชันนี้เป็นแบบธรรมดารองรับโดยเอกสารประกอบเข้าใจง่ายและใช้งานง่าย มันควรจะยอมรับ!
Carolyn Conway

ฉันลองใช้คำตอบนี้ แต่ได้ผลเพียงครั้งเดียวหลังจากรีเฟรชอีกครั้งจะไม่ได้ผล
medev21

3
เพียงแค่หมายเหตุสำหรับคนอื่น ๆ : ฉันทำapp.config['TEMPLATES_AUTO_RELOAD'] = Trueแล้วและด้วยเหตุผลบางประการคาดว่าจะเห็นเซิร์ฟเวอร์รีสตาร์ทอัตโนมัติเมื่อเทมเพลตมีการเปลี่ยนแปลงเช่นเดียวกับในโหมดดีบัก ไม่รีสตาร์ท แต่จะอัปเดตเทมเพลตที่แสดงผล
cs01

3
สาเหตุใดที่ไม่สามารถใช้งานได้กับ 0.12? หรือการตั้งค่าอื่น ๆ ที่จะทำให้ไม่สามารถตั้งค่าได้อย่างถูกต้อง?
user805981

3
@Federer ดูเหมือนจะไม่ทำงานเหมือนที่เคย ... ก่อนหน้านี้จะตรวจพบการเปลี่ยนแปลงในไดเร็กทอรี template และไดเร็กทอรีย่อยและจะโหลดเซิร์ฟเวอร์ซ้ำ .... นี่เป็นสิ่งใหม่ใน 0.12 หรือไม่ เปลี่ยนไป?
user805981

55

เมื่อคุณทำงานกับjinjaเทมเพลตคุณต้องตั้งค่าพารามิเตอร์บางอย่าง ในกรณีของฉันกับ python3 ฉันแก้ไขด้วยรหัสต่อไปนี้:

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
คุณช่วยให้ฉันมีสติ ขอบคุณ.
Nostalg.io

ฉันก็ประสบปัญหาอย่างหนักเช่นกัน ฉันดีใจที่ช่วยได้;)
silgon

สิ่งนี้ใช้ได้ผลกับฉันในขวด 1.0.2 แต่ฉันไม่มีอาร์กิวเมนต์โฮสต์
Enrico Borba

ใช่ @EnricoBorba คุณอาจไม่ต้องการมัน ฉันมักจะใช้มันเพราะฉันดีบักในโลคัลด้วยนักเทียบท่าและบางครั้งแอปพลิเคชันจำเป็นต้องเข้าถึงจากคอนเทนเนอร์อื่น อ้างอิงบางส่วน
silgon

@silgon เออเข้าใจแล้ว ส่วนใหญ่ฉันแค่เพิ่มความคิดเห็นเพื่อให้ชัดเจนเกี่ยวกับสิ่งที่ทำงานในการติดตั้งใหม่ของ Flask เวอร์ชัน 1.0.2
Enrico Borba


10

จริงๆแล้วสำหรับฉันTEMPLATES_AUTO_RELOAD = Trueไม่ทำงาน (เวอร์ชัน 0.12) ฉันใช้ jinja2 และสิ่งที่ฉันได้ทำ:

  1. สร้างฟังก์ชัน before_request

    def before_request():
        app.jinja_env.cache = {}
    
  2. ลงทะเบียนในแอปพลิเคชัน

    app.before_request(before_request)
    
  3. แค่นั้นแหละ.


3
Garret ฉันไม่ได้ทดสอบโดยไม่มีตัวเลือกเหล่านี้
dikkini

ขั้นตอนที่ 3 ไม่จำเป็นจริงๆมันใช้ได้ผลกับฉันมาก
Ricardo Ribeiro

4

สิ่งที่ใช้ได้ผลสำหรับฉันเพียงแค่เพิ่มสิ่งนี้:

@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 = {}

( นำมาจากคำตอบของ @ dikkini )


2

ใช้ Flask เวอร์ชันล่าสุดบน Windows โดยใช้คำสั่ง run และ debug ตั้งค่าเป็น true ไม่จำเป็นต้องรีเซ็ตขวดเพื่อให้การเปลี่ยนแปลงแม่แบบมีผล ลอง Shift + F5 (หรือ Shift พร้อมปุ่มโหลดซ้ำ) เพื่อให้แน่ใจว่าไม่มีการแคช


2

อัปเดตเมื่อเดือนมิถุนายน 2019:

CLI ขวดขอแนะนำมากกว่า app.run () เพื่อใช้เซิร์ฟเวอร์ dev ดังนั้นหากเราต้องการใช้ CLI แล้วการแก้ปัญหาที่ได้รับการยอมรับไม่สามารถใช้

การใช้ Flask (1.1) เวอร์ชันพัฒนาในขณะที่เขียนนี้ทำให้เราสามารถตั้งค่าตัวแปรสภาพแวดล้อม FLASK_RUN_EXTRA_FILES ซึ่งทำสิ่งเดียวกับคำตอบที่ยอมรับได้อย่างมีประสิทธิภาพ

ดูปัญหา GitHub นี้

ตัวอย่างการใช้งาน:

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

ใน Linux ในการระบุไฟล์พิเศษหลายไฟล์ให้แยกพา ธ ไฟล์ด้วยโคลอน , เช่น

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

CLI ยังสนับสนุน--extra-filesอาร์กิวเมนต์ของ Flask 1.1


การปรับปรุงเล็กน้อย ลิงก์ไปยัง 'flask CLI' จำเป็นต้องอัปเดตเป็นเวอร์ชันปัจจุบัน flask.palletsprojects.com/en/1.1.x/cli อย่างอื่นขอบคุณ :)
CodingMatters


1

แม่แบบจะโหลดใหม่โดยอัตโนมัติทำไมไม่ctrl+f5รีเฟรชหน้าเว็บเพราะปกติเว็บเบราว์เซอร์จะบันทึกแคช

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.