cmd中輸入:mkvirtualenv 環境名html
pip install flask==0.12.4 pip install redis pip install flask-session pip install flask-script pip install flask-mysqldb pip install flask-sqlalchemy pip install flask-migrate pip install flask_wtf
項目根目錄/ ├── application/ # 項目主要邏輯代碼保存目錄 | ├── apps #存放藍圖 | ├── settings/ # 項目配置存儲目錄 │ │ ├ dev.py # 開發階段的配置文件 │ │ ├ prop.py # 生產階段的配置文件 | ├──templates #存放全局的html文件 │ ├── __init__.py # 項目初始化文件 ├── manage.py # 項目的終端管理腳本文件 ├──logs/ #存放日誌文件 ├──docs/ #存放文檔文件
settings/__init__.py:python
from redis import StrictRedis class Config(object): """項目配置核心類""" # 調試模式 DEBUG = True # todo 配置日誌 pass # mysql數據庫的配置信息 SQLALCHEMY_DATABASE_URI = "mysql://root:mysql@127.0.0.1:3306/students?charset=utf8" # 動態追蹤修改設置,如未設置只會提示警告 SQLALCHEMY_TRACK_MODIFICATIONS = False # 查詢時會顯示原始SQL語句 SQLALCHEMY_ECHO= False # 配置redis REDIS_HOST = '127.0.0.1' # 項目上線之後,這個地址就會被替換成真實IP地址,mysql也是 REDIS_PORT = 6379 # 設置密鑰,能夠經過 base64.b64encode(os.urandom(48)) 來生成一個指定長度的隨機字符串 SECRET_KEY = "ghhBljAa0uzw2afLqJOXrukORE4BlkTY/1vaMuDh6opQ3uwGYtsDUyxcH62Aw3ju" # flask_session的配置信息 SESSION_TYPE = "redis" # 指定 session 保存到 redis 中 SESSION_USE_SIGNER = True # 讓 cookie 中的 session_id 被加密簽名處理 SESSION_REDIS = StrictRedis(host=REDIS_HOST, port=REDIS_PORT,db=1) # 使用 redis 的實例 PERMANENT_SESSION_LIFETIME = 24 * 60 * 60 # session 的有效期,單位是秒
settings/dev.py:mysql
from . import Config class DevelopementConfig(Config): """開發模式下的配置""" # 查詢時會顯示原始SQL語句 SQLALCHEMY_ECHO= True
settings/prop.py:redis
from . import Config class ProductionConfig(Config): """生產模式下的配置""" DEBUG = False
application/__init__.py,建立flask應用並加載配置sql
from flask import Flask from application.settings.dev import DevelopementConfig from application.settings.prop import ProductionConfig config = { "dev": DevelopementConfig, "prop": ProductionConfig, } def init_app(config_name): """項目的初始化函數""" app = Flask(__name__) # 設置配置類 Config = config[config_name] # 加載配置 app.config.from_object(Config) return app
manage.pyz中調用init_app函數,啓動項目數據庫
from application import init_app app = init_app("dev") @app.route("/") def index(): return "index" if __name__ == '__main__': app.run()
在application/__init__.py項目初始化文件中加載redis或者mysql的初始化代碼django
from flask import Flask from redis import StrictRedis from flask_wtf.csrf import CSRFProtect from flask_session import Session from application.settings.dev import DevelopementConfig from application.settings.prop import ProductionConfig config = { "dev": DevelopementConfig, "prop": ProductionConfig, } # 爲了方便redis的鏈接對象在函數外部可使用,預先設置一個全局變量,接下來在函數中用於保存redis的鏈接 redis_store = None def init_app(config_name): """項目的初始化功能""" app = Flask(__name__) # 設置配置類 Config = config[config_name] # 加載配置 app.config.from_object(Config) # redis的連接初始化 global redis_store redis_store = StrictRedis(host=Config.REDIS_HOST, port=Config.REDIS_PORT,db=0) # 開啓CSRF防範功能 CSRFProtect(app) # 開啓session功能 Session(app) # TODO 註冊藍圖對象到app應用中 return app
application/__init__.py增長代碼flask
# from flask import Flask # from redis import StrictRedis # from flask_wtf.csrf import CSRFProtect # from flask_session import Session from flask_sqlalchemy import SQLAlchemy # # from application.settings.dev import DevelopementConfig # from application.settings.prop import ProductionConfig # # config = { # "dev": DevelopementConfig, # "prop": ProductionConfig, # } # # # 爲了方便redis的鏈接對象在函數外部可使用,預先設置一個全局變量,接下來在函數中用於保存redis的鏈接 # redis_store = None db = SQLAlchemy() # # def init_app(config_name): # """項目的初始化功能""" # app = Flask(__name__) # # # 設置配置類 # Config = config[config_name] # # # 加載配置 # app.config.from_object(Config) # # # redis的連接初始化 # global redis_store # redis_store = StrictRedis(host=Config.REDIS_HOST, port=Config.REDIS_PORT,db=0) # # # 開啓CSRF防範功能 # CSRFProtect(app) # # # 開啓session功能 # Session(app) # # 配置數據庫連接 db.init_app(app) # # # TODO 註冊藍圖對象到app應用中 # # return app
manage.pycookie
from application import init_app,db from flask_script import Manager from flask_migrate import Migrate, MigrateCommand app = init_app("dev") # 使用終端腳本工具啓動和管理flask manager = Manager(app) # 啓用數據遷移工具 Migrate(app, db) # 添加數據遷移的命令到終端腳本工具中 manager.add_command('db', MigrateCommand) @app.route("/") def index(): return "index" if __name__ == '__main__': manager.run()
application/__init__.pysession
import logging from logging.handlers import RotatingFileHandler # 把日誌相關的配置封裝成一個日誌初始化函數 def setup_log(Config): # 設置日誌的記錄等級 logging.basicConfig(level=Config.LOG_LEVEL) # 調試debug級 # 建立日誌記錄器,指明日誌保存的路徑、每一個日誌文件的最大大小、保存的日誌文件個數上限 file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 300, backupCount=10) # 建立日誌記錄的格式 日誌等級 輸入日誌信息的文件名 行數 日誌信息 formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s') # 爲剛建立的日誌記錄器設置日誌記錄格式 file_log_handler.setFormatter(formatter) # 爲全局的日誌工具對象(flaskapp使用的)添加日誌記錄器 logging.getLogger().addHandler(file_log_handler)
在init_app方法中電泳上一步建立的方法,並傳入config_name
# 啓用日誌功能 setup_log(Config)
在配置文件seetings/__init__.py中,設置日誌等級
class Config(object): """項目配置核心類""" # 調試模式 DEBUG = True # todo 配置日誌 LOG_LEVEL = "DEBUG"
application下的apps目錄專門用於存放藍圖的。建立藍圖
在apps下新建一個包,藍圖名爲index,在包下面的__init.py文件中建立藍圖對象
from flask import Blueprint index_blu = Blueprint("index_blu",__name__)
在index藍圖目錄下建立對應的視圖文件,views.py
from . import index_blu @index_blu.route("/") def index(): return "首頁"
在藍圖下的__init__.py文件中引入視圖中的全部視圖
from flask import Blueprint index_blu = Blueprint("index_blu",__name__) from .views import *
在項目初始化文件application/__init__.py文件中註冊藍圖對象
# TODO 註冊藍圖對象到app應用中 # 首頁模塊 from .apps.index import index_blu app.register_blueprint(index_blu,url_prefix='')
建立模型文件models.py
# coding=utf-8 from application import db # 建立關係表,再也不建立模型,通常用於表與表之間的多對多場景 """ 表關係變量 = db.Table( "關係表表名", db.Column('字段名', 字段類型, 字段選項), # 普通字段 db.Column("字段名", 字段類型, db.ForeignKey("表名.id")), db.Column("字段名", 字段類型, db.ForeignKey("表名.id")), ) """ achievement = db.Table( "achievement", db.Column('score', db.Numeric, comment="分數"), db.Column('student_id', db.Integer, db.ForeignKey('student.id')), db.Column('course_id', db.Integer, db.ForeignKey('course.id')) ) class Student(db.Model): """學生信息""" __tablename__ = "student" id = db.Column(db.Integer, primary_key=True, comment="主鍵ID") name = db.Column(db.String(64), index=True, comment="姓名" ) sex = db.Column(db.Boolean, default=True, comment="性別") class_number = db.Column(db.String(32), nullable=True, index=True, comment="班級") age = db.Column(db.SmallInteger, comment="年齡") description = db.Column(db.Text, comment="個性簽名") courses = db.relationship( 'Course', # 模型名稱 secondary=achievement, # 表關係變量 backref='students', # 當外鍵反過來獲取主鍵信息時,使用的字段名稱,能夠自定義,接下來的使用例如: course.students 獲取某個課程下全部的學生 lazy='dynamic' ) def __repr__(self): return "%s" % self.name class Course(db.Model): """課程信息""" __tablename__ = "course" id = db.Column(db.Integer, primary_key=True,comment="主鍵ID") name = db.Column(db.String(64), unique=True,comment="課程名稱") def __repr__(self): return "%s" % self.name
數據庫遷移:
python manage.py db init python manage.py db migrate -m 'initial migration' python manage.py db upgrade
完成學生表的增刪改查
views.py
from . import index_blu from .models import Student from flask import render_template,request from application import db from flask import flash @index_blu.route("/") def index(): """學生列表""" student_list = Student.query.all() data = [] for student in student_list: print(student.sex) data.append({ "id":student.id, "name":student.name, "age":student.age, "sex":"男" if student.sex else "女", "description":student.description, "class_number":student.class_number, }) return render_template("index.html",students=data) @index_blu.route("/add",methods=["POST","GET"]) def add_student(): if request.method == "POST": # 接受數據 name = request.form.get("username") age = int( request.form.get("age") ) sex = True if request.form.get("sex") == '1' else False class_number = request.form.get("class_number") description = request.form.get("description") # 驗證數據 if age < 0 or age > 120: # 閃現信息[用於返回錯誤信息給客戶端,只顯示一次] flash("非法的年齡數值") # 保存入庫 student = Student(name=name,age=age,sex=sex,class_number=class_number,description=description) try: db.session.add(student) db.session.commit() except: # 事務回滾 db.session.rollback() return render_template("add.html")
在藍圖下創一個templates目錄,用於存放本身的模板
在index/__init__.py文件中加入
#coding=utf-8 from flask import Blueprint index_blu = Blueprint("index_blu",__name__,template_folder="templates") from .views import *
這個和django同樣的,在查找模板時,先從全局的templates找,而後再去藍圖下面的templates中找
使用後,只會出現一次的信息,叫‘閃現信息’,用於在驗證數據失敗或者一些只須要顯示一次性提示得場景。
使用方法:
在視圖中當驗證有誤時,在顯示模板以前設置flash
# 視圖函數代碼 from flask import flash flash("對不起,您還沒有登陸,請登陸!")
模板中代碼:
# 模板代碼 {% for message in get_flashed_messages() %} <span>{{message}}</span> {% endfor %}