用 Flask 来写个轻博客 (1) — 建立项目
用 Flask 来写个轻博客 (2) — Hello World!
用 Flask 来写个轻博客 (3) — (M)VC_链接 MySQL 和 SQLAlchemy
用 Flask 来写个轻博客 (4) — (M)VC_建立数据模型和表
用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解
用 Flask 来写个轻博客 (6) — (M)VC_models 的关系(one to many)
用 Flask 来写个轻博客 (7) — (M)VC_models 的关系(many to many)
用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级
用 Flask 来写个轻博客 (9) — M(V)C_Jinja 语法基础快速概览
用 Flask 来写个轻博客 (10) — M(V)C_Jinja 经常使用过滤器与 Flask 特殊变量及方法
用 Flask 来写个轻博客 (11) — M(V)C_建立视图函数
用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板
用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验
用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板
用 Flask 来写个轻博客 (15) — M(V)C_实现博文页面评论表单
用 Flask 来写个轻博客 (16) — MV(C)_Flask Blueprint 蓝图
用 Flask 来写个轻博客 (17) — MV(C)_应用蓝图来重构项目 css
工厂模式:就是经过某一个接口函数或对象来建立另外一个对象,而这个接口函数也称之为工厂函数。 工厂模式使一个类的实例化延迟到其子类。也就是说工厂模式能够推迟到在程序运行的时候才动态决定要建立哪一个类的实例,而不是在编译时就必须知道要实例化哪一个类。python
工厂函数:一个用于建立对象的接口(create_object_interface(variables)),让子类来决定(根据不一样 variables 做为条件来判断)实例化那一个类的对象。mysql
EXAMPLE:sql
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Circle(object):
def draw(self):
print 'draw circle'
class Rectangle(object):
def draw(self):
print 'draw Rectangle'
class ShapeFactory(object):
def create(self, shape):
if shape == 'Circle':
return Circle()
elif shape == 'Rectangle':
return Rectangle()
else:
return None
fac = ShapeFactory()
obj = fac.create('Circle')
obj.draw()
这样作的好处:shell
反之,也可以使用相同的 config 来生成多个相同的 app object,这对在跨多个服务器进行流量负载均衡的时候是颇有用的。数据库
jmilkfansblog/__init__.pyjson
from flask import Flask, redirect, url_for
from models import db
from controllers import blog
def create_app(object_name):
"""Create the app instance via `Factory Method`"""
app = Flask(__name__)
# Set the app config
app.config.from_object(object_name)
# Will be load the SQLALCHEMY_DATABASE_URL from config.py to db object
db.init_app(app)
@app.route('/')
def index():
# Redirect the Request_url '/' to '/blog/'
return redirect(url_for('blog.home'))
# Register the Blueprint into app object
app.register_blueprint(blog.blog_blueprint)
return app
app.config.from_object(object_name)
接收的参数定义成一个变量,这样就能够经过接收不一样类型的实参来生成不一样的 app 对象。NOTE 2:在 create_app() 这个函数中,完成了 db/config/route/blueprint 的初始化工做以后,再返回这个 app 对象。flask
manage.pyapi
import os
from flask.ext.script import Manager, Server
from flask.ext.migrate import Migrate, MigrateCommand
from jmilkfansblog import create_app
from jmilkfansblog import models
# Get the ENV from os_environ
env = os.environ.get('BLOG_ENV', 'dev')
# Create thr app instance via Factory Method
app = create_app('jmilkfansblog.config.%sConfig' % env.capitalize())
# Init manager object via app object
manager = Manager(app)
# Init migrate object via app and db object
migrate = Migrate(app, models.db)
# Create some new commands
manager.add_command("server", Server(host='192.168.1.222', port=8089))
manager.add_command("db", MigrateCommand)
@manager.shell
def make_shell_context():
"""Create a python CLI. return: Default import object type: `Dict` """
return dict(app=app,
db=models.db,
User=models.User,
Post=models.Post,
Comment=models.Comment,
Tag=models.Tag,
Server=Server)
if __name__ == '__main__':
manager.run()
EXAMPLE 1:使用默认配置服务器
(env) [root@flask-dev JmilkFan-s-Blog]# python manage.py shell
>>> app
<Flask 'jmilkfansblog'>
>>> app.config
<Config {'JSON_AS_ASCII': True, 'USE_X_SENDFILE': False, 'SQLALCHEMY_DATABASE_URI': 'mysql+pymysql://root:fanguiju@127.0.0.1:3306/myblog?charset=utf8', 'SQLALCHEMY_TRACK_MODIFICATIONS': None, 'SQLALCHEMY_POOL_SIZE': None, 'SQLALCHEMY_POOL_TIMEOUT': None, 'SESSION_COOKIE_PATH': None, 'SQLALCHEMY_RECORD_QUERIES': None, 'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_NAME': 'session', 'SQLALCHEMY_BINDS': None, 'SQLALCHEMY_POOL_RECYCLE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'LOGGER_HANDLER_POLICY': 'always', 'LOGGER_NAME': 'jmilkfansblog', 'DEBUG': True, 'SQLALCHEMY_COMMIT_ON_TEARDOWN': False, 'SECRET_KEY': 'c8e6ff3e4687709ca10a1138a17cd397', 'EXPLAIN_TEMPLATE_LOADING': False, 'SQLALCHEMY_NATIVE_UNICODE': None, 'MAX_CONTENT_LENGTH': None, 'SQLALCHEMY_ECHO': False, 'APPLICATION_ROOT': None, 'SERVER_NAME': None, 'PREFERRED_URL_SCHEME': 'http', 'JSONIFY_PRETTYPRINT_REGULAR': True, 'TESTING': False, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31), 'PROPAGATE_EXCEPTIONS': None, 'TEMPLATES_AUTO_RELOAD': None, 'TRAP_BAD_REQUEST_ERRORS': False, 'JSON_SORT_KEYS': True, 'JSONIFY_MIMETYPE': 'application/json', 'SQLALCHEMY_MAX_OVERFLOW': None, 'SESSION_COOKIE_HTTPONLY': True, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SESSION_COOKIE_SECURE': False, 'TRAP_HTTP_EXCEPTIONS': False}>
EXAMPLE 2:手动设置使用 Config 配置
(env) [root@flask-dev JmilkFan-s-Blog]# export BLOG_ENV=""
(env) [root@flask-dev JmilkFan-s-Blog]# echo $BLOG_ENV
(env) [root@flask-dev JmilkFan-s-Blog]# python manage.py shell
>>> app.config
<Config {'JSON_AS_ASCII': True, 'USE_X_SENDFILE': False, 'SQLALCHEMY_DATABASE_URI': 'sqlite://', 'SQLALCHEMY_TRACK_MODIFICATIONS': None, 'SQLALCHEMY_POOL_SIZE': None, 'SQLALCHEMY_POOL_TIMEOUT': None, 'SESSION_COOKIE_PATH': None, 'SQLALCHEMY_RECORD_QUERIES': None, 'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_NAME': 'session', 'SQLALCHEMY_BINDS': None, 'SQLALCHEMY_POOL_RECYCLE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'LOGGER_HANDLER_POLICY': 'always', 'LOGGER_NAME': 'jmilkfansblog', 'DEBUG': False, 'SQLALCHEMY_COMMIT_ON_TEARDOWN': False, 'SECRET_KEY': 'c8e6ff3e4687709ca10a1138a17cd397', 'EXPLAIN_TEMPLATE_LOADING': False, 'SQLALCHEMY_NATIVE_UNICODE': None, 'MAX_CONTENT_LENGTH': None, 'SQLALCHEMY_ECHO': False, 'APPLICATION_ROOT': None, 'SERVER_NAME': None, 'PREFERRED_URL_SCHEME': 'http', 'JSONIFY_PRETTYPRINT_REGULAR': True, 'TESTING': False, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31), 'PROPAGATE_EXCEPTIONS': None, 'TEMPLATES_AUTO_RELOAD': None, 'TRAP_BAD_REQUEST_ERRORS': False, 'JSON_SORT_KEYS': True, 'JSONIFY_MIMETYPE': 'application/json', 'SQLALCHEMY_MAX_OVERFLOW': None, 'SESSION_COOKIE_HTTPONLY': True, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SESSION_COOKIE_SECURE': False, 'TRAP_HTTP_EXCEPTIONS': False}>
使用工厂函数生成的 app 对象,可以在程序运行的时候才被决定,这种自动适应不一样运行环境的能力,使得程序更加灵活、健壮。