生產環境下Flask項目目錄構建

   接觸Flask已經有大半年了,本篇博客主要來探討如何規範化生產環境下Flask的項目目錄結構。雖然目錄結構見仁見智,我的有我的的見解和習慣,但總的來講,通過不少人的實踐和總結,仍是有不少共同的意見和想法的,而我在查看他人的目錄結構結合自身在工做中的使用經驗,總結了一個我的認爲比較恰當的目錄結構供參考。python

   我推薦的目錄結構:nginx

. ├── README.md ├── application │ ├── __init__.py │ ├── controllers │ │ └── __init__.py │ ├── forms │ │ └── __init__.py │ ├── models │ │ └── __init__.py │ ├── services │ │ └── __init__.py │ ├── static │ │ └── __init__.py │ ├── templates │ │ └── __init__.py │ └── utils │ └── __init__.py ├── config │ ├── __init__.py │ ├── default.py │ ├── development.py │ ├── development_sample.py │ ├── production.py │ ├── production_sample.py │ └── testing.py ├── deploy │ ├── flask_env.sh │ ├── gunicorn.conf │ ├── nginx.conf │ └── supervisor.conf ├── manage.py ├── pylintrc ├── requirements.txt ├── tests │ └── __init__.py └── wsgi.py

 這裏稍做介紹,首先是第一級目錄的話,主要分爲兩類,一類是目錄,另外一類是運行相關的文件;其中目錄有:git

  • application:項目全部邏輯代碼都放這
  • config:項目的配置文件,按不一樣環境各佔一份
  • deploy:部署相關的文件,後續將使用到
  • tests:單元測試代碼所在的目錄

文件的話分別有:github

  • manage.py:Flask-Script 運行文件,後面介紹
  • pylintrc:靜態分析代碼使用的 pylint 標準
  • requirements.txt:項目依賴庫的列表
  • wsgi.py:wsgi 運行的文件

規範代碼到指定目錄

既然咱們已經規定好了目錄結構,是時候將咱們的意麪分到各個盤子裏了。首先從文件開始,由於咱們尚未介紹 Flask-Script,靜態檢查和 wsgi,因此就忽略這些文件,那麼就剩下 requirements.txt 文件了。數據庫

Flask==0.10.1 flask-mongoengine==0.7.5 Flask-Login==0.3.2 Flask-Admin==1.4.0 Flask-Redis==0.1.0 Flask-WTF==0.12

而後是時候解耦代碼了,咱們沒有表單,暫時沒有 services,沒有靜態文件也沒有頁面模板,因此能夠這樣合併:json

  • 將 route 代碼放到 application/controllers 中
  • 將 model 代碼放到 application/models 中
  • 將初始化綁定 app 的代碼放到 application/init.py 中
  • 將 數據庫等配置放到 config/development.py 中

最後就是編寫 manager.py 文件了。這裏概要得列舉幾個重要的文件,更多的文件你們能夠從 github 上 clone 代碼出來閱讀。flask

合併後的文件manager.py:app

# coding: utf-8
from flask.ext.script import Manager from application import create_app # Used by app debug & livereload PORT = 8080 app = create_app() manager = Manager(app) @manager.command def run(): """Run app.""" app.run(port=PORT) if __name__ == "__main__": manager.run()

application/init.py:dom

# coding: utf-8 import sys import os # Insert project root path to sys.path project_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) if project_path not in sys.path: sys.path.insert(0, project_path) import logging from flask import Flask from flask_wtf.csrf import CsrfProtect from config import load_config from application.extensions import db, login_manager from application.models import User from application.controllers import user_bp # convert python's encoding to utf8
try: reload(sys) sys.setdefaultencoding('utf8') except (AttributeError, NameError): pass def create_app(): """Create Flask app.""" config = load_config() print config app = Flask(__name__) app.config.from_object(config) if not hasattr(app, 'production'): app.production = not app.debug and not app.testing # CSRF protect CsrfProtect(app) if app.debug or app.testing: # Log errors to stderr in production mode app.logger.addHandler(logging.StreamHandler()) app.logger.setLevel(logging.ERROR) # Register components register_extensions(app) register_blueprint(app) return app def register_extensions(app): """Register models.""" db.init_app(app) login_manager.init_app(app) login_manager.login_view = 'login' @login_manager.user_loader def load_user(user_id): return User.objects(id=user_id).first() def register_blueprint(app): app.register_blueprint(user_bp)

application/controllers/init.py:單元測試

#!/usr/bin/env python # encoding: utf-8 import json from flask import Blueprint, request, jsonify from flask.ext.login import current_user, login_user, logout_user from application.models import User user_bp = Blueprint('user', __name__, url_prefix='') @user_bp.route('/login', methods=['POST']) def login(): info = json.loads(request.data) username = info.get('username', 'guest') password = info.get('password', '') user = User.objects(name=username, password=password).first() if user: login_user(user) return jsonify(user.to_json()) else: return jsonify({"status": 401, "reason": "Username or Password Error"}) @user_bp.route('/logout', methods=['POST']) def logout(): logout_user() return jsonify(**{'result': 200, 'data': {'message': 'logout success'}}) @user_bp.route('/user_info', methods=['POST']) def user_info(): if current_user.is_authenticated: resp = {"result": 200, "data": current_user.to_json()} else: resp = {"result": 401, "data": {"message": "user no login"}} return jsonify(**resp)

config/development.py:

# coding: utf-8 import os class DevelopmentConfig(object): """Base config class.""" # Flask app config DEBUG = False TESTING = False SECRET_KEY = "sample_key" # Root path of project PROJECT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) # Site domain SITE_TITLE = "twtf" SITE_DOMAIN = "http://localhost:8080" # MongoEngine config MONGODB_SETTINGS = { 'db': 'the_way_to_flask', 'host': 'localhost', 'port': 27017 }

   若是你有更好的項目目錄結構,歡迎交流!要特別說明下,這篇博客以前就記錄在個人印象筆記上,我是直接搬過來的,因此格式方面就很難看了!這得感謝同事黃俊,以前是沒有寫博客的習慣的,都是直接記錄在印象筆記上!哈哈

相關文章
相關標籤/搜索