笔者以前未接触过 Python,只是略懂一点前端,因此说从零开始也相差无几吧。Flask 是一个轻量级的基于 Python 的框架,可是扩展性很是良好(Github 上 22000 多个 star 就知道群众的选择不无道理),其余的这里就很少提了,下面就开始咱们的网站搭建之路。html
首先须要准备 Python 开发环境,这里推荐使用 pyenv 来安装和管理 Python。笔者使用的是 Mac OSX(自带 Python 2.6),直接使用以下命令安装 pyenv:前端
brew install pyenv
以后要升级 pyenv 的话就用:python
brew upgrade pyenv
安装完之后,须要配置环境变量,若是使用 zsh,须要在 ~/.zshrc 加入如下代码:git
export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" export PATH=$PATH:/sbin/ eval "$(pyenv init -)"
若是使用 bash,在 ~/.bash_profile 中加入便可。保存后重启终端便可。
若是要安装 Python 3.5.2,能够用github
pyenv install 3.5.2
查看安装的 Python 版本:sql
pyenv versions
切换局部 Python 环境(这里通常指在 Application 文件夹下切换环境)shell
pyenv local 3.5.2
关于其余更多命令,能够参考 Command.md数据库
这里笔者推荐使用 PyCharm 来进行 python 项目开发。下载安装后(这里笔者下载的是 Professional 版本),新建一个 Flask 项目,而后指定目录、python 环境:flask
完成后点击 Create,这样就建立了一个 Flask 项目,若是没有安装 Flask,PyCharm 会自动下载安装。若是想使用 virtualenv,能够参考下一个步骤。浏览器
使用虚拟环境能够方便地安装 Flask 并且能够在系统的 Python 解释器中避免包的混乱和版本的冲突。Python 3.3之后原生支持虚拟环境,命令为 pyvenv。可使用以下命令建立虚拟环境(进入刚才建立的 Flask 项目文件夹):
pyvenv venv
若是使用 Python 2.7或者如下版本,可使用第三方工具 virtualenv 建立虚拟环境:
sudo easy_install virtualenv
以上命令就能够安装 virtualenv(若是没有安装 easy_install,须要手动安装,而 pyvenv 已经自带 pip 和 easy_install)。下一步使用 virtualenv 命令在文件夹中建立 Python 虚拟环境:
virtualenv venv
完成后,会在 Flask 项目下生成 venv 文件夹。在使用虚拟环境以前,要先使用(pyvenv 和 virtualenv 建立的虚拟环境是同样的,所以如下命令都可使用):
source venv/bin/activate
来激活,若是要退出虚拟环境,可使用:
deactivate
建立的虚拟环境会自动安装 pip 和 easy_install,接下来可使用:
pip install flask
接下来就能够在 Flask 中开始自由地遨(入)游(坑)啦!
在介绍 Flask 的程序结构以前,先来看看标准 Flask 项目的项目结构(笔者觉得从宏观到微观的方式能够更快的了解一个东西)。使用 PyCharm 新建 Flask 项目后,项目结构以下图所示:
只有三个文件夹(venv 文件夹已经用命令行生成了)和一个简单的入口类,接下来要把项目结构改形成标准的 Flask 项目结构:
Flask 项目有4个顶级文件夹:
同时还有一些文件:
虽然新建的 Flask Project 已经能够运行,可是咱们仍是要按照标准的 Flask 程序来改造项目结构。下面咱们就来改造一下 TestProject。
在命令行中依次使用如下命令来安装 Flask 扩展:
pip install flask-script pip install flask-sqlalchemy pip install flask-migrate
flask-script 能够自定义命令行命令,用来启动程序或其它任务;flask-sqlalchemy 用来管理数据库的工具,支持多种数据库后台;flask-migrate 是数据库迁移工具,该工具命令集成到 flask-script 中,方便在命令行中进行操做。
而后建立 config.py 文件,内容以下:
config.py
import os basedir = os.path.abspath(os.path.dirname(__file__)) class config: SECRET_KEY = os.environ.get('SECRET_KEY') or 'this is a secret string' SQLALCHEMY_TRACK_MODIFICATIONS = True @staticmethod def init_app(app): pass class DevelopmentConfig(config): DEBUG = True SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \ 'sqlite:///' + os.path.join(basedir, 'dev') class TestingConfig(config): TESTING = True SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \ 'sqlite:///' + os.path.join(basedir, 'test') class ProductionConfig(config): SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \ 'sqlite:///' + os.path.join(basedir, 'data.sqlite') config = { 'development': DevelopmentConfig, 'testing': TestingConfig, 'production': ProductionConfig, 'default': DevelopmentConfig }
config 顾名思义,保存了一些配置变量。SQLALCHEMY_DATABASE_URI 变量在不一样的配置中被赋予了不一样的值,这样就能够在不一样的环境中切换数据库。若是是远程数据库则从环境变量中读取 URL,不然在本地路径中建立。
接下来建立一个 app 文件夹,并在此文件夹中建立一个 __init__.py 文件(init 先后都有两个下划线):
app/__init__.py
from flask import Flask from flask_sqlalchemy import SQLAlchemy from config import config db = SQLAlchemy() def create_app(config_name): app = Flask(__name__) app.config.from_object(config[config_name]) config[config_name].init_app(app) db.init_app(app) //此处缺省了部分代码,后面会加上 return app
create_app() 就是程序的工厂函数,参数就是配置类的名字,即 config.py,其中保存的配置可使用 from_object() 方法导入。
接下来要解释两个重要的概念——路由和视图函数。客户端把请求发给 Web 服务器,Web 服务器再把请求发给 Flask 程序实例,Flask 程序实例须要知道每一个 URL 请求要运行哪些代码,因此保存了一个 URL 到 Python 函数的映射关系。处理 URL 和函数之间关系的程序称为路由,这个函数称为视图函数。例如:
@app.route('/') def index(): return '<h1>Hello World</h1>'
这里使用 app.route 修饰器来定义路由,app 指 Flask 程序实例对象,后面能够看到使用蓝本管理路由后,由蓝本实例对象来取代 app。Flask 使用蓝原本定义路由,在蓝本中定义的路由处于休眠状态,直到蓝本注册到程序上后,路由真正成为程序的一部分。蓝本一般使用结构化的方式保存在包的多个模块中。接下来在 app 文件夹下建立一个子文件夹 main,并在 main 中建立 __init__.py(若是使用 PyCharm,这里有个快捷方式,右键点击 app 文件夹,在菜单中选择 new -> Python Package,在弹出的对话框中填写包名而后确认便可):
app/main/__ init__.py
from flask import Blueprint //实例化 Blueprint 类,两个参数分别为蓝本的名字和蓝本所在包或模块,第二个一般填 __name__ 便可 main = Blueprint('main', __name__) from . import views, errors
最后引用了两个文件,之因此写在最后是由于避免循环导入依赖,由于接下来在 main 文件夹下 建立的 views.py 和 errors.py 都要导入蓝本 main。
app/main/views.py
from flask import render_template //导入蓝本 main from . import main @main.route('/') def index(): return render_template('index.html')
在以前路由的概念解释中,index 函数直接返回了 HTML 字符串(一般不这么作),这里则使用了 render_templete() 函数来渲染 index.html,并返回。Flask 使用了 Jinja2 引擎来渲染模板,模板文件都放在 templates 文件夹下,而且只能命名为 templates,不然 Jinja2 会抛出 TemplageNotFound 异常。因为咱们的app 是一个 Python Package(在目录中包含 init.py 默认成为 Python Package),因此须要将 templates 放在 app 目录下。在 app 下 中建立名为 templates 的文件夹,在 PyCharm 中右键点击该文件夹,而后选择 Make Directory As -> Template Folder,如图:
接下来在 templates 下新建一个 index.html 和 404.html 模板:
app/templates/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <h1>Hello World</h1> </body> </html>
app/templates/404.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Not Found</title> </head> <body> <h1>Can't find request page!</h1> </body> </html>
以后会讲解模板的具体用法,如今接着来定义 errors.py:
app/main/errors.py
from flask import render_template from . import main @main.app_errorhandler(404) def page_not_found(e): return render_template('404.html'), 404
上面的步骤是让程序的路由保存在 views.py 中,而错误处理交给 errors.py,这两个模块已经和蓝本 main 关联起来了(在蓝本中导入了这两个模块),如今须要在工厂函数中注册蓝本 main。将以下代码加入到上面缺省代码中便可:
app/__init__.py
def create_app(config_name): #... from .main import main as main_blueprint app.register_blueprint(main_blueprint) return app
最后两个步骤是建立 requirements.txt 以及启动脚本 manage.py。程序中必须包含一个 requirements.txt 文件,用于记录全部的依赖包和版本号,便于在其它电脑上建立相同的开发环境。直接在终端使用以下命令便可建立 requirements.txt 文件:
pip freeze > requirements.txt
之后安装了新的依赖包或者升级版本后,从新执行该命令便可更新 requirements.txt 文件。若是要手动添加也能够,在 PyCharm 中用 Command + , 唤出 Preferences 对话框,而后选择 Project -> Project Interpreter 便可查看全部的依赖包及其版本号(还有最新版本号提示),如图:
若是要在另外一台电脑上建立这个虚拟环境的彻底副本,运行如下命令便可:
pip install -r requirements.txt
最后建立启动脚本 manage.py:
manage.py
import os from app import create_app, db from flask_script import Manager, Shell from flask_migrate import Migrate, MigrateCommand app = create_app(os.getenv('FLASK_CONFIG') or 'default') manager = Manager(app) migrate = Migrate(app, db) def make_shell_context(): return dict(app=app, db=db) manager.add_command("shell",Shell(make_context=make_shell_context)) manager.add_command('db', MigrateCommand) if __name__ == '__main__': manager.run()
这个脚本首先建立程序,而后增长了两个命令:shell 和 db,咱们以后能够在命令行中直接使用。
到此为止,咱们的目录结构以下:
如今就来启动咱们的程序,在命令行中进入 TestProject 目录,而后执行以下命令便可运行:
python manage.py runserver
命令行运行截图以下:
Flask 默认的本机地址为:http://127.0.0.1:5000/ ,如今用浏览器打开这个地址,应该能够看到以下页面:
到这一步,咱们的第一个 Flask 程序已经完成了!虽然尚未创建数据库,页面也很是糟糕,可是以后咱们会一步步进行完善!
本文参考书籍 Flask Web 开发:基于 Python 的 Web 应用开发实战(做者: Miguel Grinberg)
做者:KenChoi - 极光
原文:从零开始用 Flask 搭建一个网站(一)
知乎专栏:极光日报