ïŒ2018幎çïŒ
ãã²ã«ã»ã°ãªã³ããŒã°
ããã« æ»ã 
ããã¯ãFlask Mega-Tutorialsã·ãªãŒãºã®15çªç®ã§ãããå€§èŠæš¡ãªã¢ããªã±ãŒã·ã§ã³ã«é©ããã¹ã¿ã€ã«ã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãåæ§ç¯ããŸãã
ãã¿ãã¬ã®äžã«ã¯ããã®2018幎ã·ãªãŒãºã®ãã¹ãŠã®èšäºã®ãªã¹ãããããŸãã
泚1ïŒãã®ã³ãŒã¹ã®å€ãããŒãžã§ã³ããæ¢ãã®å Žåã¯ããã¡ããã芧ãã ãã ã
泚2ïŒç§ïŒãã²ã«ïŒã®ä»äºãæ¯æããŠçªç¶å£°ãããããå ŽåããŸãã¯1é±éèšäºãåŸ
ã€å¿èããªãå Žåãç§ïŒãã²ã«ã°ãªãŒã³ããŒã°ïŒã¯ãã®ã¬ã€ãã®å®å
šçïŒè±èªïŒãé»åæžç±ãŸãã¯ãããªã®åœ¢åŒã§æäŸããŸãã 詳现ã«ã€ããŠã¯ã learn.miguelgrinberg.comãã芧ãã ãã ã
ãã€ã¯ãããã°ã¯ãã§ã«ãŸãšããªãµã€ãºã®ã¢ããªã§ãïŒ ãããŠãFlaskã¢ããªã±ãŒã·ã§ã³ãæ··ä¹±ããããšãªãããŸãã¯ç®¡çããã«ã¯ããŸãã«ãè€éã«ãªãããšãªããã©ã®ããã«æé·ã§ããããè°è«ããæã ãšæããŸããã Flaskã¯ããããžã§ã¯ããä»»æã®æ¹æ³ã§æŽçããæ©äŒãæäŸããããã«èšèšããããã¬ãŒã ã¯ãŒã¯ã§ãããã®å²åŠã®äžç°ãšããŠãã¢ããªã±ãŒã·ã§ã³ã倧ãããªãã«ã€ããŠããŸãã¯ããŒãºãçµéšã¬ãã«ãå€åããã«ã€ããŠãã¢ããªã±ãŒã·ã§ã³ã®æ§é ã倿ŽãŸãã¯é©åãããããšãã§ããŸãã
ãã®ç« ã§ã¯ãå€§èŠæš¡ãªã¢ããªã±ãŒã·ã§ã³ã«é©çšãããããã€ãã®ãã¿ãŒã³ã«ã€ããŠèª¬æããããããå®èšŒããããã«ãã³ãŒããããä¿å®ããããç·šæããããããããã«ãç§ã®ãã€ã¯ãããã°ãããžã§ã¯ãã®æ§é ã«ããã€ãã®å€æŽãå ããŸãã ãããããã¡ãããFlaskã®çã®ç²Ÿç¥ã§ã¯ããããã®å€æŽãæšå¥šäºé
ãã€ãŸãç¬èªã®ãããžã§ã¯ããç·šæããæ¹æ³ãšããŠã®ã¿åãå
¥ããããšããå§ãããŸãã
ãã®ç« ã®GitHubãªã³ã¯ïŒ Browse ã Zip ã Diff ã
çŸåšã®å¶é
ã¢ããªã±ãŒã·ã§ã³ã®çŸåšã®ç¶æ
ã«ã¯ãäž»ã«2ã€ã®åé¡ããããŸãã ã¢ããªã±ãŒã·ã§ã³ã®æ§é ãèŠããšãèå¥ã§ãããµãã·ã¹ãã ãããã€ãããããšãããããŸããããããããµããŒãããã³ãŒãã¯æç¢ºãªå¢çãªãã«ãã¹ãŠæ··åãããŠããŸãã ãããã®ãµãã·ã¹ãã ãäœã§ãããèŠãŠã¿ãŸãããïŒ
- app / routes.pyã®è¡šç€ºæ©èœã app / forms.pyã®ãã©ãŒã ã app / templatesã®ãã³ãã¬ãŒã ã app / email.pyã®ã¡ãŒã«ãµããŒããå«ããŠãŒã¶ãŒèªèšŒãµãã·ã¹ãã ã
- app / errors.pyã®ãšã©ãŒãã³ãã©ãŒãšapp / templatesã®ãã³ãã¬ãŒããå®çŸ©ãããšã©ãŒãµãã·ã¹ãã ã
- ããã°æçš¿ããŠãŒã¶ãŒãããã¡ã€ã«ãããã³åŸç¶ã€ãã³ãã®è¡šç€ºãšèšé²ãããã³å€æ°ã®ã¢ããªã±ãŒã·ã§ã³ã¢ãžã¥ãŒã«ãšãã³ãã¬ãŒãã§é
åžãããããã°æçš¿ã®ã©ã€ã翻蚳ãå«ããã¢ããªã±ãŒã·ã§ã³ã®äž»ãªæ©èœã
ç§ãå®çŸ©ãããããã®3ã€ã®ãµãã·ã¹ãã ãšããããã©ã®ããã«æ§æãããŠããããèãããšããããããã¿ãŒã³ã«æ°ä»ãã§ãããã ãããŸã§ãç§ãåŸã£ãçµç¹ã®ããžãã¯ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ããŸããŸãªæ©èœã«é¢ããã¢ãžã¥ãŒã«ã®å¯çšæ§ã«åºã¥ããŠããŸãã æ©èœã衚瀺ããããã®ã¢ãžã¥ãŒã«ãWebãã©ãŒã çšããšã©ãŒçšãã¬ã¿ãŒçšãHTMLãã³ãã¬ãŒãçšã®ãã£ã¬ã¯ããªãªã©ããããŸãã ããã¯å°èŠæš¡ãªãããžã§ã¯ãã«ã¯çã«ããªã£ãæ§é ã§ããããããžã§ã¯ããæé·ãå§ãããšããããã®ã¢ãžã¥ãŒã«ã®ããã€ããæ¬åœã«å€§ããæ±ããªãåŸåããããŸãã
åé¡ãæç¢ºã«èŠã1ã€ã®æ¹æ³ã¯ãæåã®ãããžã§ã¯ãããå¯èœãªéãåå©çšããŠã2çªç®ã®ãããžã§ã¯ããéå§ããæ¹æ³ãæ€èšããããšã§ãã ããšãã°ããŠãŒã¶ãŒèªèšŒéšåã¯ä»ã®ã¢ããªã±ãŒã·ã§ã³ã§ããŸãæ©èœããã¯ãã§ãã ãã ãããã®ã³ãŒãããã®ãŸãŸäœ¿çšããå Žåã¯ãããã€ãã®ã¢ãžã¥ãŒã«ã«ç§»åããé©åãªã»ã¯ã·ã§ã³ãã³ããŒããŠãæ°ãããããžã§ã¯ãã®æ°ãããã¡ã€ã«ã«è²Œãä»ããå¿
èŠããããŸãã ãããã©ãã»ã©äžäŸ¿ããã芧ãã ããã ãã®ãããžã§ã¯ãã«ãä»ã®ã¢ããªã±ãŒã·ã§ã³ãšã¯å¥ã«èªèšŒé¢é£ã®ãã¡ã€ã«ããã¹ãŠå«ãŸããŠããã°ãããè¯ããšæããŸãããïŒ Flask ã®ãã«ãŒããªã³ãæ©èœã¯ãã³ãŒãã®åå©çšãç°¡çŽ åãããããå®çšçãªçµç¹ã®å®çŸã«åœ¹ç«ã¡ãŸãã
2çªç®ã®åé¡ã¯ããã»ã©æçœã§ã¯ãããŸããã Flaskã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã¯app/__init__.py
ã°ããŒãã«å€æ°ãšããŠäœæããããã®åŸå€ãã®ã¢ããªã±ãŒã·ã§ã³ã¢ãžã¥ãŒã«ã«ãã£ãŠã€ã³ããŒããããŸãã ããèªäœã¯åé¡ã§ã¯ãããŸããããã¢ããªã±ãŒã·ã§ã³ãã°ããŒãã«å€æ°ãšããŠäœ¿çšãããšãç¹ã«ãã¹ãã«é¢é£ããããã€ãã®ã·ããªãªãè€éã«ãªãå¯èœæ§ããããŸãã ããŸããŸãªæ§æã§ãã®ã¢ããªã±ãŒã·ã§ã³ããã¹ããããšããŸãã ã¢ããªã±ãŒã·ã§ã³ã¯ã°ããŒãã«å€æ°ãšããŠå®çŸ©ãããŠãããããå®éã«ã¯ãç°ãªãæ§æå€æ°ã䜿çšããŠ2ã€ã®ã¢ããªã±ãŒã·ã§ã³ãã€ã³ã¹ã¿ã³ã¹åããããšã¯ã§ããŸããã çæ³çã§ã¯ãªãå¥ã®ç¶æ³ã¯ããã¹ãŠã®ãã¹ããåãã¢ããªã±ãŒã·ã§ã³ã䜿çšãããããåŸã§å®è¡ãããå¥ã®ãã¹ãã«åœ±é¿ãåãŒãã¢ããªã±ãŒã·ã§ã³ã«å€æŽãå ããããšãã§ããããšã§ãã çæ³çã«ã¯ããã¹ãŠã®ãã¹ããå
ã®ã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã§å®è¡ããå¿
èŠããããŸãã
å®éãããããã¹ãŠã¯tests.pyã¢ãžã¥ãŒã«ã§èŠãããšãã§ããŸãã ãã£ã¹ã¯ããŒã¹ã®SQLiteããŒã¿ããŒã¹ïŒããã©ã«ãïŒã®ä»£ããã«ã¡ã¢ãªå
ã®ããŒã¿ããŒã¹ã䜿çšããããã«ãã¹ããæç€ºããããã«ãã¢ããªã±ãŒã·ã§ã³ã«ã€ã³ã¹ããŒã«ããåŸã®æ§æå€æŽã®ããªãã¯ã«é ŒããŸãã ãã¹ããéå§ãããæç¹ã§ãã¢ããªã±ãŒã·ã§ã³ã¯æ¢ã«äœæããã³æ§æãããŠãããããæ§ææžã¿ããŒã¿ããŒã¹ã倿Žããä»ã®æ¹æ³ã¯ãããŸããã ãã®ç¹å®ã®ç¶æ³ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã«é©çšãããåŸã«æ§æã倿ŽãããšããŸãããããã«èŠããŸãããä»ã®å Žåã«ã¯åœ¹ã«ç«ããããããã®å Žåãæªãç·Žç¿ã§ããããããŸãã§ãšã©ãŒãèŠã€ããã®ãé£ãããªããŸãã
æåã®è§£æ±ºçã¯ãã¢ããªã±ãŒã·ã§ã³ã«ã°ããŒãã«å€æ°ã䜿çšããã代ããã«ã¢ããªã±ãŒã·ã§ã³ãã¡ã¯ããªé¢æ°ã䜿çšããŠå®è¡æã«é¢æ°ãäœæããããšã§ãã ããã¯ãæ§æãªããžã§ã¯ããåŒæ°ãšããŠåãåãããããã®èšå®ã«ãã£ãŠæ§æãããFlaskã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ãè¿ã颿°ã«ãªããŸãã ã¢ããªã±ãŒã·ã§ã³ã倿ŽããŠã¢ããªã±ãŒã·ã§ã³ãã¡ã¯ããªé¢æ°ã䜿çšã§ããããã«ãããšãåãã¹ãã§ç¬èªã®ã¢ããªã±ãŒã·ã§ã³ãäœæã§ãããããç¹å¥ãªæ§æãå¿
èŠãšãããã¹ãã®äœæã容æã«ãªããŸãã
ãã®ç« ã§ã¯ãäžèšã®3ã€ã®ãµãã·ã¹ãã ã®èŠçŽ å³ãšã¢ããªã±ãŒã·ã§ã³ãã¡ã¯ããªé¢æ°ãå°å
¥ããŠãã¢ããªã±ãŒã·ã§ã³ãåç·šæããŸãã 倿Žã®è©³çްãªãªã¹ãã衚瀺ããããšã¯å®çšçã§ã¯ãããŸãããã¢ããªã±ãŒã·ã§ã³ã®äžéšã§ããã»ãšãã©ãã¹ãŠã®ãã¡ã€ã«ã«å°ããªå€æŽãããããããªãã¡ã¯ã¿ãªã³ã°ãè¡ãããã«è¡ã£ãæé ã«ã€ããŠèª¬æããŸãããããã®å€æŽãå«ãã¢ããªã±ãŒã·ã§ã³ãããŠã³ããŒãã§ããŸã ã
èšèšå³
Flaskã§ã¯ããããžã§ã¯ãã¯ã¢ããªã±ãŒã·ã§ã³ã®ãµãã»ããã§ããè«çæ§é ã§ãã ãããžã§ã¯ãã«ã¯ãã«ãŒãã衚瀺æ©èœããã©ãŒã ããã³ãã¬ãŒããéçãã¡ã€ã«ãªã©ã®èŠçŽ ãå«ããããšãã§ããŸãã ãããžã§ã¯ããå¥ã®Pythonããã±ãŒãžã§èšè¿°ããå Žåãç¹å®ã®ã¢ããªã±ãŒã·ã§ã³æ©èœã«é¢é£ããèŠçŽ ãã«ãã»ã«åããã³ã³ããŒãã³ãããããŸãã
ã¹ããŒãèŠçŽ ã®å
å®¹ã¯æåã¯éæ¢ããŠããŸãã ãããã®èŠçŽ ããªã³ã¯ããã«ã¯ãèŠçŽ å³ãã¢ããªã±ãŒã·ã§ã³ã«ç»é²ããå¿
èŠããããŸãã ç»é²æã«ãèŠçŽ å³ã«è¿œå ããããã¹ãŠã®èŠçŽ ãã¢ããªã±ãŒã·ã§ã³ã«è»¢éãããŸãã ãããã£ãŠãèŠçŽ å³ãã¢ããªã±ãŒã·ã§ã³ã®æ©èœã®äžæã¹ãã¬ãŒãžãšããŠæç€ºããããšãã§ããã³ãŒãã®æŽçã«åœ¹ç«ã¡ãŸãã
ãã«ãŒããªã³ããšã©ãŒåŠç
æåã«äœæããèŠçŽ å³ã¯ããšã©ãŒãã³ãã©ããµããŒãããããã«ã«ãã»ã«åãããŸããã ãã®æŠå¿µã®æ§é ã¯æ¬¡ã®ãšããã§ãã
app/ errors/ <-- blueprint __init__.py <-- blueprint handlers.py <-- error templates/ errors/ <-- error 404.html 500.html __init__.py <-- blueprint
æ¬è³ªçã«ã app / errors.pyã¢ãžã¥ãŒã«ãapp / errors / handlers.pyã«ç§»åãã app / templates / errorsã®2ã€ã®ãšã©ãŒãã¿ãŒã³ãä»ã®ãã¿ãŒã³ããåé¢ããŸããã ãŸããäž¡æ¹ã®ãšã©ãŒãã³ãã©ãŒã§render_template()
åŒã³åºãã倿ŽããŠãæ°ãããšã©ãŒãã³ãã¬ãŒãã®ãµããã£ã¬ã¯ããªã䜿çšããå¿
èŠããããŸããã ãã®åŸããã«ãŒããªã³ããapp/errors/__init__.py
ã«äœæããã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã®äœæåŸã«ãããžã§ã¯ããapp/__init__.py
ã«ç»é²ããŸããã
FlaskèŠçŽ ã®ã¹ããŒãã¯ããã³ãã¬ãŒããŸãã¯éçãã¡ã€ã«çšã®å¥ã®ãã£ã¬ã¯ããªã§æ§æã§ããããšã«æ³šæããŠãã ããã ãã¹ãŠã®ãã³ãã¬ãŒããåãéå±€ã«ããããã«ããã³ãã¬ãŒããã¢ããªã±ãŒã·ã§ã³ãã³ãã¬ãŒããã£ã¬ã¯ããªã®ãµããã£ã¬ã¯ããªã«ç§»åããããšã«ããŸããããèŠçŽ ã¹ããŒã ããã±ãŒãžå
ã®èŠçŽ ã¹ããŒã ã«å±ãããã³ãã¬ãŒãã䜿çšããå Žåã¯ãããããµããŒããããŠããŸãã ããšãã°ãåŒæ°template_folder= 'templates'
ãBlueprint()
ã³ã³ã¹ãã©ã¯ã¿ãŒã«è¿œå ãããšãèŠçŽ ã¬ã€ã¢ãŠããã³ãã¬ãŒããapp / errors / templatesã«ä¿åã§ããŸãã
èŠçŽ å³ã®äœæã¯ãã¢ããªã±ãŒã·ã§ã³ã®äœæãšéåžžã«äŒŒãŠããŸãã ããã¯ãblueprintããã±ãŒãžã®__init__.py
ã¢ãžã¥ãŒã«ã§è¡ãããŸãã
app/errors/__init__.py
ïŒãšã©ãŒã®ãã«ãŒããªã³ãã
from flask import Blueprint bp = Blueprint('errors', __name__) from app.errors import handlers
Blueprint
ã¯ã©ã¹ã¯ãèŠçŽ ã¹ããŒãã®ååãããŒã¹ã¢ãžã¥ãŒã«ã®ååïŒéåžžã¯Flaskã¢ããªã±ãŒã·ã§ã³ã®ã€ã³ã¹ã¿ã³ã¹ã®ããã«__name__
ã«èšå®ãããŸãïŒãããã³ãã®å Žåã¯å¿
èŠãªãããã€ãã®ãªãã·ã§ã³ã®åŒæ°ãåããŸãã èŠçŽ å³ãªããžã§ã¯ããäœæãããã handlers.pyã¢ãžã¥ãŒã«ãã€ã³ããŒãããŠããã®äžã®ãšã©ãŒãã³ãã©ãŒãèŠçŽ å³ã«ç»é²ãããããã«ããŸãã 埪ç°äŸåé¢ä¿ãé¿ããããããã®ã€ã³ããŒãã¯äžéšã«ãããŸãã
handlers.pyã¢ãžã¥ãŒã«ã§ã¯ã @app.errorhandler
ãã³ã¬ãŒã¿ãŒã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã«ãšã©ãŒãã³ãã©ãŒãã¢ã¿ãããã代ããã«ããã«ãŒããªã³ããã³ã¬ãŒã¿ãŒ@bp.app_errorhandler
ã䜿çšããŸãã äž¡æ¹ã®ãã³ã¬ãŒã¿ã¯åãæçµçµæãéæããŸãããã¢ã€ãã¢ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ç¬ç«ããèŠçŽ ã®ã¬ã€ã¢ãŠããäœæããŠãç§»æ€æ§ãé«ããããšã§ãã ãŸãã2ã€ã®ãšã©ãŒãã¿ãŒã³ãžã®ãã¹ã倿ŽããŠãç§»åå
ã®æ°ãããšã©ãŒãµããã£ã¬ã¯ããªã«å¯Ÿå¿ããå¿
èŠããããŸãã
ãšã©ãŒãã³ãã©ã®ãªãã¡ã¯ã¿ãªã³ã°ãå®äºããæåŸã®æé ã¯ãèŠçŽ ã¹ããŒããã¢ããªã±ãŒã·ã§ã³ã«ç»é²ããããšã§ãã
app/__init__.py
ïŒèŠçŽ ã¹ããŒã ãã¢ããªã±ãŒã·ã§ã³ã«ç»é²ããŸãã
app = Flask(__name__) # ... from app.errors import bp as errors_bp app.register_blueprint(errors_bp) # ... from app import routes, models # <-- !
ã¢ã€ãã ã¹ããŒããç»é²ããã«ã¯ãFlaskã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã®register_blueprint()
ã¡ãœããã䜿çšããŸãã èŠçŽ å³ãç»é²ãããšããã¹ãŠã®ãã¬ãŒã³ããŒã·ã§ã³é¢æ°ããã³ãã¬ãŒããéçãã¡ã€ã«ããšã©ãŒãã³ãã©ãªã©ãã¢ããªã±ãŒã·ã§ã³ã«æ¥ç¶ãããŸãã 埪ç°äŸåé¢ä¿ãé¿ããããã«ãèŠçŽ ã¹ããŒãã®ã€ã³ããŒããapp.register_blueprint()
ããäžã«app.register_blueprint()
ãŸãã
ãã«ãŒããªã³ãèªèšŒ
ã¢ããªã±ãŒã·ã§ã³ã®èªèšŒæ©èœããããžã§ã¯ãã«ãªãã¡ã¯ã¿ãªã³ã°ããããã»ã¹ã¯ããšã©ãŒãã³ãã©ãŒãåŠçããããã»ã¹ãšéåžžã«äŒŒãŠããŸãã ãªãã¡ã¯ã¿ãªã³ã°ã¹ããŒã ã¯æ¬¡ã®ãšããã§ãã
app/ auth/ <-- blueprint __init__.py <-- blueprint email.py <-- authentication emails forms.py <-- authentication forms routes.py <-- authentication routes templates/ auth/ <-- blueprint login.html register.html reset_password_request.html reset_password.html __init__.py <-- blueprint
ãã®ãããžã§ã¯ããäœæããã«ã¯ãèªèšŒã«é¢é£ãããã¹ãŠã®æ©èœãããããžã§ã¯ãã§äœæããæ°ããã¢ãžã¥ãŒã«ã«è»¢éããå¿
èŠããããŸããã ããã«ã¯ãããã€ãã®ãã©ãŠãžã³ã°æ©èœãWebãã©ãŒã ãããã³ãã¹ã¯ãŒããªã»ããããŒã¯ã³ãé»åã¡ãŒã«ã§éä¿¡ããæ©èœãªã©ã®ãµããŒãæ©èœãå«ãŸããŸãã ãšã©ãŒããŒãžã®å Žåãšåæ§ã«ããã³ãã¬ãŒãããµããã£ã¬ã¯ããªã«ç§»åããŠãã¢ããªã±ãŒã·ã§ã³ã®ä»ã®éšåããåé¢ããŸããã
èŠçŽ å³ã§ã«ãŒããå®çŸ©ãããšãã @bp.route
代ããã«@app.route
ãã³ã¬ãŒã¿ãŒã䜿çšããŸãã ãŸããURLãäœæããã«ã¯ã url_for()
䜿çšãããæ§æã倿Žããå¿
èŠããããŸãã ã¢ããªã±ãŒã·ã§ã³ã«çŽæ¥æ¥ç¶ãããŠããéåžžã®ãã¥ãŒé¢æ°ã®å Žåã url_for()
æåã®åŒæ°ã¯ãã¥ãŒé¢æ°ã®ååã§ãã ã«ãŒããèŠçŽ ãããã§å®çŸ©ãããŠããå Žåããã®åŒæ°ã«ã¯ãèŠçŽ ãããã®ååãšãã¥ãŒé¢æ°ã®ååãããªãªãã§åºåã£ãŠå«ããå¿
èŠããããŸãã ãã®ãããããšãã°ããã¹ãŠã®url_for('login')
ãurl_for('auth.')
ã«url_for('auth.')
ãæ®ãã®ãã¬ãŒã³ããŒã·ã§ã³é¢æ°ã«ã€ããŠãåãããã«çœ®ãæããå¿
èŠããããŸããã
auth
èŠçŽ ã®ã¹ããŒããã¢ããªã±ãŒã·ã§ã³ã«ç»é²ããããã«ãå°ãç°ãªã圢åŒã䜿çšããŸããã
app/__init__.py
ïŒèªèšŒèŠçŽ ã¹ããŒã ãã¢ããªã±ãŒã·ã§ã³ã«ç»é²ããŸãã
# ... from app.auth import bp as auth_bp app.register_blueprint(auth_bp, url_prefix='/auth') # ...
ãã®å Žåã®register_blueprint()
ã®åŒã³åºãã«ã¯ã远å ã®url_prefix
åŒæ°ããããŸãã ããã¯å®å
šã«ãªãã·ã§ã³ã§ãããFlaskã¯èŠçŽ ããããURLãã¬ãã£ãã¯ã¹ã®äžã«ã¢ã¿ããããæ©èœãæäŸãããããèŠçŽ ãããã§å®çŸ©ãããã«ãŒãã¯ãã¹ãŠURLã§ãã®ãã¬ãã£ãã¯ã¹ãååŸããŸãã å€ãã®å Žåãããã¯ãèŠçŽ å³ã®ãã¹ãŠã®ã«ãŒããã¢ããªã±ãŒã·ã§ã³ãŸãã¯ä»ã®èŠçŽ å³ã®ä»ã®ã«ãŒãããåé¢ããäžçš®ã®ãåå空éããšããŠåœ¹ç«ã¡ãŸãã èªèšŒã«ã€ããŠã¯ããã¹ãŠã®ã«ãŒãã/auth
ã§å§ãŸãã®ããããšæã£ãã®ã§ããã¬ãã£ãã¯ã¹ã远å ããŸããã ãããã£ãŠããã°ã€ã³URLã¯httpïŒ// localhostïŒ5000 / auth / loginã«ãªããŸã ã url_for()
ã䜿çšããŠURLãçæããããããã¹ãŠã®URLã«èªåçã«ãã¬ãã£ãã¯ã¹ãå«ãŸããŸãã
ã¢ããªã±ãŒã·ã§ã³èŠçŽ ã®åºæ¬çãªæŠèŠ
3çªç®ã®èŠçŽ å³ã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ããžãã¯ãå«ãŸããŠããŸãã ãã®èŠçŽ å³ããªãã¡ã¯ã¿ãªã³ã°ããã«ã¯ãåã®2ã€ã®èŠçŽ å³ãšåãããã»ã¹ãå¿
èŠã§ãã ãã®èŠçŽ ã¹ããŒã ã«main
ãšããååãä»ããã®ã§ããã¥ãŒé¢æ°ãåç
§ãããã¹ãŠã®url_for()
åŒã³åºãã«ã¯main
å¿
èŠã§ãã ãã¬ãã£ãã¯ã¹ã ãããã¢ããªã±ãŒã·ã§ã³ã®äž»èŠãªæ©èœã§ããããããã³ãã¬ãŒããåãå Žæã«æ®ãããšã«ããŸããã ãã³ãã¬ãŒããä»ã®2ã€ã®èŠçŽ ã¹ããŒã ãããµããã£ã¬ã¯ããªã«ç§»åãããããããã¯åé¡ã§ã¯ãããŸããã
ã¢ããªã±ãŒã·ã§ã³ãã¡ã¯ããªãã³ãã¬ãŒã
ãã®ç« ã®æŠèŠã§è¿°ã¹ãããã«ãã¢ããªã±ãŒã·ã§ã³ãã°ããŒãã«å€æ°ãšããŠäœ¿çšãããšãäž»ã«ããã€ãã®ãã¹ãã·ããªãªã®å¶éãšãã圢ã§ãããã€ãã®è€éããçããŸãã èŠçŽ å³ã玹ä»ããåã«ãã¢ããªã±ãŒã·ã§ã³ã¯ã°ããŒãã«å€æ°ã§ãªããã°ãªããŸãã@app.route
ããªããªãããã¹ãŠã®ãã¬ãŒã³ããŒã·ã§ã³é¢æ°ãšãšã©ãŒãã³ãã©ãŒã¯ã @app.route
ãªã©ã®app
颿°ã§è£
食ããå¿
èŠããã£ãããapp
ã ãããããã¹ãŠã®ã«ãŒããšãšã©ãŒãã³ãã©ãŒãèŠçŽ ã¹ããŒãã«ç§»åããããããã¢ããªã±ãŒã·ã§ã³ãã°ããŒãã«ã«ä¿ã€çç±ã¯ã¯ããã«å°ãªããªããŸããã
ãããã£ãŠãFlaskã¢ããªã±ãŒã·ã§ã³ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããã°ããŒãã«å€æ°ãé€å€ããcreate_app()
颿°ã远å ããŸãã 倿ã¯ç°¡åã§ã¯ãããŸããã§ããããããã€ãã®å°é£ãçè§£ããå¿
èŠããããŸããããæåã«ã¢ããªã±ãŒã·ã§ã³ãã¡ã¯ããªé¢æ°ãèŠãŠã¿ãŸãããã
app/__init__.py
ïŒã¢ããªã±ãŒã·ã§ã³ãã¡ã¯ããªé¢æ°ã
# ... db = SQLAlchemy() migrate = Migrate() login = LoginManager() login.login_view = 'auth.login' login.login_message = _l('Please log in to access this page.') mail = Mail() bootstrap = Bootstrap() moment = Moment() babel = Babel() def create_app(config_class=Config): app = Flask(__name__) app.config.from_object(config_class) db.init_app(app) migrate.init_app(app, db) login.init_app(app) mail.init_app(app) bootstrap.init_app(app) moment.init_app(app) babel.init_app(app) # ... blueprint registration if not app.debug and not app.testing: # ... logging setup return app
ã»ãšãã©ã®Flaskæ¡åŒµæ©èœã¯ãæ¡åŒµæ©èœãã€ã³ã¹ã¿ã³ã¹åããã¢ããªã±ãŒã·ã§ã³ãåŒæ°ãšããŠæž¡ãããšã§åæåãããããšãããããŸããã ã¢ããªã±ãŒã·ã§ã³ãã°ããŒãã«å€æ°ãšããŠååšããªãå Žåãæ¡åŒµæ©èœã2ã€ã®ã¹ãããã§åæåããã代æ¿ã¢ãŒãããããŸãã æ¡åŒµã€ã³ã¹ã¿ã³ã¹ã¯ã以åãšåæ§ã«ã°ããŒãã«ã¹ã³ãŒãã§æåã«äœæãããŸãããåŒæ°ã¯æž¡ãããŸããã ããã«ãããã¢ããªã±ãŒã·ã§ã³ã«æ·»ä»ãããŠããªãæ¡åŒµæ©èœã®ã€ã³ã¹ã¿ã³ã¹ãäœæãããŸãã ãã¡ã¯ããªãŒé¢æ°ã§ã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ãäœæããå Žåãæ¡åŒµã€ã³ã¹ã¿ã³ã¹ã§init_app()
ã¡ãœãããåŒã³åºããŠãæ¢ç¥ã®ã¢ããªã±ãŒã·ã§ã³ã«ãã€ã³ãããå¿
èŠããããŸãã
åæåäžã«å®è¡ãããä»ã®ã¿ã¹ã¯ã¯å€æŽãããŸããããã°ããŒãã«ã¹ã³ãŒãå
ã§ã¯ãªããã¡ã¯ããªé¢æ°ã«è»¢éãããŸãã ããã«ã¯ãèŠçŽ ã¹ããŒããšãã®ã³ã°æ§æã®ç»é²ãå«ãŸããŸãã æ¡ä»¶ã«not app.testing
æ¡ä»¶ã远å ããããšã«æ³šæããŠãã ãããããã¯ããŠããããã¹ãäžã«ãããã®ãã°ããã¹ãŠã¹ããããããããã«ãé»åã¡ãŒã«ãšãã¡ã€ã«ã®ãã°ãæå¹ãŸãã¯ç¡å¹ã«ãããã©ãããæ±ºå®ããŸãã æ§æã§TESTING
倿°ãTrue
ã«èšå®ãããŠãããããåäœãã¹ãã®å®è¡æã«app.testing
ãã©ã°ã¯True
ã«ãªããŸãã
ã§ã¯ã誰ãã¢ããªã±ãŒã·ã§ã³ãã¡ã¯ããªé¢æ°ãåŒã³åºãã®ã§ããããïŒ ãã®æ©èœã䜿çšããæçœãªå Žæã¯ããããã¬ãã«ã¹ã¯ãªããmicroblog.pyã§ã ãããã¯ãã¢ããªã±ãŒã·ã§ã³ãçŸåšã°ããŒãã«ãšãªã¢ã«ååšããå¯äžã®ã¢ãžã¥ãŒã«ã§ãã å¥ã®å Žæã¯test.pyã§ã次ã®ã»ã¯ã·ã§ã³ã§ãŠããããã¹ãã«ã€ããŠè©³ãã説æããŸãã
äžã§è¿°ã¹ãããã«ãã¢ããªã±ãŒã·ã§ã³ãžã®ãªã³ã¯ã®ã»ãšãã©ã¯èŠçŽ ã¹ããŒãã®å°å
¥ãšãšãã«ãªããªããŸãããããããã®ããã€ãã¯ãŸã èæ
®ãã¹ãã³ãŒãã«æ®ã£ãŠããŸãã ããšãã°ããã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³app / models.py ã app / translate.pyããã³app / main / routes.pyã«ã¯app.configãžã®ãªã³ã¯ããããŸãã 幞ããªããšã«ãFlaskéçºè
ã¯ããããŸã§è¡ã£ãŠããããã«ãã€ã³ããŒãããããšãªãã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã«ã¢ã¯ã»ã¹ããããã«ãã©ãŠãžã³ã°æ©èœãç°¡çŽ åããããšããŸããã Flaskã®current_app
倿°ã¯ããªã¯ãšã¹ããéä¿¡ããåã«ã¢ããªã±ãŒã·ã§ã³ãåæåããç¹å¥ãªãã³ã³ããã¹ããFlask倿°ã§ãã 以åã«å¥ã®ã³ã³ããã¹ã倿°ãã€ãŸãçŸåšã®ãã±ãŒã«ãä¿åããg
倿°ãèŠãŠããŸããã ããã2ã€ã¯ã current_user
Flask-Loginããã³ãŸã èŠãããšã®ãªãä»ã®ããã€ããšäžç·ã«ãã°ããŒãã«å€æ°ãšããŠæ©èœããããæ¡ä»¶ä»ãã®ãããžãã¯ã倿°ã§ããããªã¯ãšã¹ãåŠçäžããã³ãããåŠçããã¹ã¬ããã§ã®ã¿äœ¿çšå¯èœã§ãã
app
ãFlaskã®current_app
倿°ã«çœ®ãæãããšãã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ãã°ããŒãã«å€æ°ãšããŠã€ã³ããŒãããå¿
èŠããªããªããŸãã app.config
ãã¹ãŠã®èšè¿°ãcurrent_app.config
ç°¡åãªæ€çŽ¢ãšçœ®æã§ç°¡åã«çœ®ãæããããšãã§ããŸããã
app / email.pyã¢ãžã¥ãŒã«ã¯å°ã倧ããªåé¡ã ã£ãã®ã§ãã¡ãã£ãšããããªãã¯ã䜿ããªããã°ãªããŸããã§ããã
app / email.py ïŒã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ãå¥ã®ã¹ã¬ããã«è»¢éããŸãã
from app import current_app def send_async_email(app, msg): with app.app_context(): mail.send(msg) def send_email(subject, sender, recipients, text_body, html_body): msg = Message(subject, sender=sender, recipients=recipients) msg.body = text_body msg.html = html_body Thread(target=send_async_email, args=(current_app._get_current_object(), msg)).start()
send_email()
颿°ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ãåŒæ°ãšããŠããã¯ã°ã©ãŠã³ãã¹ã¬ããã«æž¡ãããã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ããããã¯ããã«é»åã¡ãŒã«ãé
ä¿¡ãããŸãã current_app
ã¯ã¯ã©ã€ã¢ã³ãèŠæ±ãåŠçããã¹ã¬ããã«ãã€ã³ããããã³ã³ããã¹ã倿°ã§ãããããããã¯ã°ã©ãŠã³ãã¹ã¬ãããšããŠæ©èœããsend_async_email()
颿°ã§current_app
çŽæ¥äœ¿çšããŠãæ©èœããŸããã å¥ã®ã¹ã¬ããã§ã¯ã current_app
ã¯å€ãå²ãåœãŠãããŠããŸããã current_app
ã¯å®éã«ã¯ã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã«åçã«ãããããããããã·ãªããžã§ã¯ãã§ããããã current_app
åŒæ°ãšããŠã¹ããªãŒã ãªããžã§ã¯ãã«çŽæ¥æž¡ãããšãæ©èœããŸããã ãããã£ãŠããããã·ãªããžã§ã¯ããæž¡ãããšã¯ãã¹ããªãŒã å
ã§current_app
çŽæ¥äœ¿çšããããšãšåãã«ãªããŸãã ãããã·ãªããžã§ã¯ãå
ã«æ ŒçŽãããŠããã¢ããªã±ãŒã·ã§ã³ã®å®éã®ã€ã³ã¹ã¿ã³ã¹ã«ã¢ã¯ã»ã¹ãããããã¢ããªã±ãŒã·ã§ã³ã®åŒæ°ãšããŠæž¡ãå¿
èŠããããŸããã åŒcurrent_app._get_current_object()
ã¯ããããã·ãªããžã§ã¯ãããå®éã®ã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ãååŸãããããããã¯åŒæ°ãšããŠã¹ããªãŒã ã«æž¡ãããã®ã§ãã
ãã1ã€ã®ãããŒãã±ãŒã¹ãã¯app / cli.pyã¢ãžã¥ãŒã«ã§ ãããã¯èšèªç¿»èš³ã管çããããã®ããã€ãã®ã¯ã€ãã¯ã¢ã¯ã»ã¹ã³ãã³ããå®è£
ããŠããŸãã ãã®å Žåã倿°current_app
ã¯æ©èœããŸããããããã®ã³ãã³ãã¯ããªã¯ãšã¹ãã®åŠçäžã§ã¯ãªããèµ·åæã«ç»é²ãããããã§ããããã¯ã current_app
ã䜿çšã§ããå¯äžã®æéã§ãã ãã®ã¢ãžã¥ãŒã«ã§ã¢ããªã±ãŒã·ã§ã³ãžã®ãªã³ã¯ãåé€ããããã«ãå¥ã®ããªãã¯ã«é ŒããŸããããããã®ãŠãŒã¶ãŒã³ãã³ããregister()
颿°å
ã«ç§»åãã app
ã€ã³ã¹ã¿ã³ã¹ãåŒæ°ãšããŠäœ¿çšããŸãã
app / cli.py ïŒã«ã¹ã¿ã ã¢ããªã±ãŒã·ã§ã³ã³ãã³ããç»é²ããŸãã
import os import click def register(app): @app.cli.group() def translate(): """Translation and localization commands.""" pass @translate.command() @click.argument('lang') def init(lang): """Initialize a new language.""" # ... @translate.command() def update(): """Update all languages.""" # ... @translate.command() def compile(): """Compile all languages.""" # ...
次ã«ã microblog.pyãããã®register()
颿°ãåŒã³åºããŸããã ãªãã¡ã¯ã¿ãªã³ã°åŸã®å®å
šãªmicroblog.pyã¯æ¬¡ã®ãšããã§ãã
microblog.py ïŒãªãã¡ã¯ã¿ãªã³ã°åŸã®ã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ã¢ãžã¥ãŒã«ã
from app import create_app, db, cli from app.models import User, Post app = create_app() cli.register(app) @app.shell_context_processor def make_shell_context(): return {'db': db, 'User': User, 'Post' :Post}
åäœãã¹ãã®æ¹å
ãã®ç« ã®åé ã§ç€ºåããããã«ããããŸã§ã«è¡ã£ãäœæ¥ã®ã»ãšãã©ã¯ãåäœãã¹ãã®ã¯ãŒã¯ãããŒãæ¹åããããšãç®çãšããŠããŸãã åäœãã¹ããå®è¡ããå Žåãã¢ããªã±ãŒã·ã§ã³ãããŒã¿ããŒã¹ãªã©ã®éçºãªãœãŒã¹ã«å¹²æžããªãããã«æ§æãããŠããããšã確èªããå¿
èŠããããŸãã
tests.pyã®çŸåšã®ããŒãžã§ã³ã¯ãã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã«é©çšãããåŸã«æ§æã倿Žãããšããããªãã¯ã«é ŒããŸããããã¯ãæåŸã®ç¬éã«ãã¹ãŠã®ã¿ã€ãã®å€æŽãæ©èœããããã§ã¯ãªããããå±éºãªæ
£è¡ã§ãã ãã¹ãæ§æãã¢ããªã±ãŒã·ã§ã³ã«è¿œå ããåã«æå®ã§ããããã«ãããã
create_app()
颿°ã¯ãæ§æã¯ã©ã¹ãåŒæ°ãšããŠcreate_app()
ããã«ãªããŸããã ããã©ã«ãã§ã¯ã config.pyã§å®çŸ©ãããConfig
ã¯ã©ã¹ã䜿çšãããŸãããæ°ããã¯ã©ã¹ããã¡ã¯ããªãŒé¢æ°ã«æž¡ãã ãã§ãç°ãªãæ§æã䜿çšããã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ãäœæã§ããããã«ãªããŸããã ãŠããããã¹ãã«äœ¿çšã§ããæ§æã¯ã©ã¹ã®äŸã次ã«ç€ºããŸãã
tests.py ïŒèšå®ã®ãã¹ãã
from config import Config class TestConfig(Config): TESTING = True SQLALCHEMY_DATABASE_URI = 'sqlite://'
ããã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®Config
ã¯ã©ã¹ããµãã¯ã©ã¹åããSQLAlchemyæ§æããªãŒããŒã©ã€ãããŠãã¡ã¢ãªå
ã®SQLiteããŒã¿ããŒã¹ã䜿çšããŸãã ãŸããå€Trueã®TESTING
屿§ã远å ããŸããããããã¯çŸåšå¿
èŠãããŸããããã¢ããªã±ãŒã·ã§ã³ãåäœãã¹ãã§å®è¡ããããã©ããã倿ããå¿
èŠãããå Žåã«åœ¹ç«ã¡ãŸãã
æãåºããŠããã ããã°ãç§ã®ãŠããããã¹ãã¯setUp()
ããã³tearDown()
ã¡ãœããã«åºã¥ããŠããŸããããããã®ã¡ãœããã¯ãåãã¹ãã«é©ããç°å¢ãäœæããã³ç Žæ£ããããã«ãŠããããã¹ããã©ãããã©ãŒã ã«ãã£ãŠèªåçã«åŒã³åºãããŸãã :
tests.py : .
class UserModelCase(unittest.TestCase): def setUp(self): self.app = create_app(TestConfig) self.app_context = self.app.app_context() self.app_context.push() db.create_all() def tearDown(self): db.session.remove() db.drop_all() self.app_context.pop()
self.app
, , . db.create_all()
, . db
, , URI app.config
, , , . , db
, self.app
, ?
. current_app
, - , ? , , . , , , current_app
. , Python. , python
, flask shell
, , .
>>> from flask import current_app >>> current_app.config['SQLALCHEMY_DATABASE_URI'] Traceback (most recent call last): ... RuntimeError: Working outside of application context. >>> from app import create_app >>> app = create_app() >>> app.app_context().push() >>> current_app.config['SQLALCHEMY_DATABASE_URI'] 'sqlite:////home/miguel/microblog/app.db'
! Flask , current_app
g
. , . db.create_all()
setUp()
, db.create_all()
current_app.config
, , . tearDown()
, .
, , Flask. request context , , . , request
session
Flask, current_user
Flask-Login.
, , , , , . , , URL- API Microsoft Translator. , , , , , , .
, , .env
. , .
Python, .env , python-dotenv
. , :
(venv) $ pip install python-dotenv
config.py â , , .env Config
, :
config.py : .env .
import os from dotenv import load_dotenv basedir = os.path.abspath(os.path.dirname(__file__)) load_dotenv(os.path.join(basedir, '.env')) class Config(object): # ...
, .env , . , .env - . , , .
.env - , FLASK_APP
FLASK_DEBUG
, , , .
.env , , 25- , API Microsoft Translator :
SECRET_KEY=a-really-long-and-unique-key-that-nobody-knows MAIL_SERVER=localhost MAIL_PORT=25 MS_TRANSLATOR_KEY=<your-translator-key-here>
Requirements
Python. - , , , requirements.txt . :
(venv) $ pip freeze > requirements.txt
pip freeze
, , , requirements.txt . , , , :
(venv) $ pip install -r requirements.txt
ããã« æ»ã 