flask 项目的开发经验总结
=========================
目录结构
=========================
考虑到项目的扩展性, 采用 blueprint 进行组织. 假设 flaskapp 为根目录, 主要的程序放在 app 包中, 除了后台代码, 在app目录下还有templates/static/子目录. 为了重用, 最好的形式是一个建立 boilerplate 项目.
主要参考文档为:
https://github.com/mitsuhiko/flask/wiki/Large-app-how-to
http://www.realpython.com/blog/python/python-web-applications-with-flask-part-ii-app-creation
http://www.realpython.com/blog/python/rethink-flask-a-simple-todo-list-powered-by-flask-and-rethinkdb/
flaskapp
├── app
│ ├── __init__.py
│ ├── constants.py
│ ├── users[sub_app/module]
│ │ ├── constants.py
│ │ ├── decorators.py
│ │ ├── forms.py
│ │ ├── models.py
│ │ └── views.py
│ ├── tickets[sub_app/module]
│ │ ├── constants.py
│ │ ├── decorators.py
│ │ ├── forms.py
│ │ ├── models.py
│ │ └── views.py
│ ├── templates
│ │ ├── forms
│ │ │ └── macros.html
│ │ ├── base.html
│ │ ├── index.html
│ │ ├── base_another.html
│ │ ├── 500.html (server error page)
│ │ ├── 404.html (not found page)
│ │ ├── method_not_allowed.html
│ │ ├── access_forbidden.html
│ │ ├── users
│ │ │ ├── profile.html
│ │ │ ├── login.html
│ │ │ └── register.html
│ │ └── tickets
│ │ ├── create.html
│ │ └── close.html
│ └── static
│ ├── favicon.ico
│ ├── img
│ ├── js
│ │ ├── main.js #our own js code
│ │ └── vendor
│ │ ├── bootstrap.min.js
│ │ └── jquery-1.7.2.min.js
│ └── css
│ ├── layout.less
│ ├── reset.less
│ └── vendor
│ └── bootstrap.css
├── flaskapp.db
├── config.py
├── requirements.txt
├── runserver.py
├── shell.py
├── tests 目录
└── docs 目录
----------------------
项目级的单元
----------------------
runserver.py 用来启动 web server, 从app包中进入flask app对象, 然后直接启动.
config.py 存储一些db的 connection 配置, 以及Flask SECRET_KEY 等等. 更多的配置项见 http://flask.pocoo.org/docs/config/
----------------------
应用级别的单元
----------------------
flaskapp/app/__init__.py, 作为整个app的入口, 做如下工作.
1.加载flask的config,
2.[如使用Flask-SQLAlchemy插件]创建 SqlAlchemy 的db 实例.
3.[如没使用Flask-SQLAlchemy插件]定义3个函数, 分别加上@app.before_request和@app.teardown_request和@app.after_request. before_request和teardown_request函数非常适合做创建和关闭db connection工作. after_request函数不适合用来关闭db connection, 因为after_request函数在有unhandled exception发生的情况下, 会被跳过. 而teardown 函数总是能保证被调用的.
4.注册sub app blueprint, 比如users和tickets
5.设置root url 和favicon.ico 的路由,
6.创建login_manager, 比如使用flask-login插件来创建一个login_manager
----------------------
子应用级别的单元,
----------------------
flaskapp/app/users/models.py, 和User相关的表模型
flaskapp/app/users/constants.py, 和User module相关的constant, 比如用户的激活状态, 用户的类型.
flaskapp/app/users/forms.py, 集中所有User module相关的表单类, 比如class LoginForm(Form) 和 class RegisterForm(Form) 类.
flaskapp/app/users/decorators.py, 和User module相关的一些decorator, 比如 requires_login, 供 views.py 使用.
flaskapp/app/users/views.py, 充当url路由角色(Flask是基于MVT模型, 这里的view相当于MVC模型中的Controller). 依据web请求类型和请求的url, 路由到指定的view函数, 在view函数中, 做逻辑处理, 然后, 或展现form, 或跳转到其他url.
----------------------
templates目录
----------------------
flaskapp/app/templates/base.html, 模板的模板, 根据需要, 可以设置多个base页面
flaskapp/app/templates/forms/macros.html, 定义一些宏, 供form页面调用, 用来渲染form的元素
flaskapp/app/templates/users/login.html, 在flaskapp/app/users/views.py应该有一个同名的view函数
----------------------
static目录
----------------------
flaskapp/app/static/favicon.ico, 16 × 16 pixels and in the ICO format
=========================
源码示例
=========================
------------------------------
runserver.py
------------------------------
runserver.py 用来启动 web server.
# -*- coding: utf-8 -*-
from __future__ import absolute_import from app import app app.run()
------------------------------
config.py
------------------------------
config.py 存储一些db的 connection 配置, 以及Flask SECRET_KEY 等等. 更多的配置项见 http://flask.pocoo.org/docs/config/
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import os
from datetime import timedelta
_basedir = os.path.abspath(os.path.dirname(__file__)) DEBUG = True SECRET_KEY = os.urandom(24)
PERMANENT_SESSION_LIFETIME=timedelta(seconds=24*60*60) CSRF_ENABLED = True
CSRF_SESSION_KEY = SECRET_KEY
------------------------------
app/__init__.py
------------------------------
flaskapp/app/__init__.py, 作为整个app的入口, 做如下工作.
1.加载flask的config,
2.[如使用Flask-SQLAlchemy插件]创建 SqlAlchemy 的db 实例.
3.[如没使用Flask-SQLAlchemy插件]定义3个函数,
分别加上@app.before_request和@app.teardown_request和@app.after_request.
before_request和teardown_request函数非常适合做创建和关闭db connection工作.
after_request函数不适合用来关闭db connection, 因为after_request函数在有unhandled
exception发生的情况下, 会被跳过. 而teardown 函数总是能保证被调用的.
4.注册sub app blueprint, 比如users和tickets
5.设置root url 和favicon.ico 的路由,
6.创建login_manager, 比如使用flask-login插件来创建一个login_manager
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from flask import Flask, g, render_template, send_from_directory
import os
import os.path
_basedir = os.path.abspath(os.path.dirname(__file__))
configPy=os.path.join(os.path.join( _basedir,os.path.pardir), 'config.py') app = Flask(__name__) # create our application object app.config.from_pyfile(configPy)
#app.debug=True #change some attribute after load configuration flask_sqlalchemy_used=True # 如果使用Flask-SQLAlchemy了
db = SQLAlchemy(app) #create a db (SQLAlchemy) object from our app object login_manager = LoginManager(app) #create a LoginManager Object from our app object
#add our view as the login view to finish configuring the LoginManager
login_manager.login_view = "users.login_view" #register the users module blueprint
from app.users.views import mod as usersModule
app.register_blueprint(usersModule) #register the tickets module blueprint
from app.tickets.views import mod as ticketsModule
app.register_blueprint(ticketsModule) def connect_db(): # 如果没使用Flask-SQLAlchemy
if not flask_sqlalchemy_used:
return sqlite3.connect('/path/to/database.db')
else:
return None @app.before_request
def before_request():
"""Make sure we are connected to the database each request."""
if not flask_sqlalchemy_used:
g.db = connect_db() @app.teardown_request
def teardown_request(response):
"""Closes the database again at the end of the request."""
if not flask_sqlalchemy_used:
g.db.close()
return response #*****************
# controllers
#***************** @app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path, 'static'), 'ico/favicon.ico') @app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404 @app.route("/")
def index():
return render_template('index.html')
------------------------------
app/users/views.py.py
------------------------------
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from flask import Blueprint, render_template, flash, redirect, session, url_for, request, g
from flask.ext.login import login_user, logout_user, login_required
from app import app, db, login_manager
from forms import LoginForm, RegistrationForm
from app.users.models import User mod = Blueprint('users', __name__) #register the users blueprint module @login_manager.user_loader
def load_user(user_id):
return User.query.get(user_id) @mod.route('/login/', methods=('GET', 'POST'))
def login_view():
form = LoginForm(request.form)
if form.validate_on_submit():
user = form.get_user()
login_user(user)
flash("Logged in successfully.")
return redirect(request.args.get("next") or url_for("index"))
return render_template('users/login.html', form=form) @mod.route('/register/', methods=('GET', 'POST'))
def register_view():
form = RegistrationForm(request.form)
if form.validate_on_submit():
user = User()
form.populate_obj(user)
db.session.add(user) #使用SqlAlchemy保存
db.session.commit()
login_user(user)
return redirect(url_for('index'))
return render_template('users/register.html', form=form) @login_required
@mod.route('/logout/')
def logout_view():
logout_user()
return redirect(url_for('index'))
macros.html, 是个jinja2的宏文件, 我们在该文件中可定义一些宏, 供form页面调用, 用来渲染form的元素. 用法是, 在我们的html文件中, 引入这个宏文件即可.
用法:
{% from "macros.html" import form_field %}
macros.html内容, 可以自动将form兼容 bootstrap. 内容摘自 https://gist.github.com/rawrgulmuffins/6025599
{% macro form_field(field) -%}
{% set with_label = kwargs.pop('with_label', False) %}
{% set placeholder = '' %}
{% if not with_label %}
{% set placeholder = field.label.text %}
{% endif %}
<div class="control-group {% if field.errors %}error{% endif %}">
{% if with_label %}
<label for="{{ field.id }}" class="control-label">
{{ field.label.text }}{% if field.flags.required %} *{% endif %}:
</label>
{% endif %}
<div class="controls">
{% set class_ = kwargs.pop('class_', '') %}
{% if field.flags.required %}
{% set class_ = class_ + ' required' %}
{% endif %}
{% if field.type == 'BooleanField' %}
<label class="checkbox">
{{ field(class_=class_, **kwargs) }}
{{ field.label.text|safe }}
</label>
{% else %}
{% if field.type in ('TextField', 'TextAreaField', 'PasswordField') %}
{% set class_ = class_ + ' input-xlarge' %}
{% elif field.type == 'FileField' %}
{% set class_ = class_ + ' input-file' %}
{% endif %} {% if field.type == 'SelectField' %}
{{ field(class_=class_, **kwargs) }}
{% else %}
{{ field(class_=class_, placeholder=placeholder, **kwargs) }}
{% endif %} {% endif %}
{% if field.errors %}
<span class="error help-inline">{{ field.errors|join(', ') }}</span>
{% endif %}
{% if field.description %}
<p class="help-block">{{ field.description|safe }}</p>
{% endif %}
</div>
</div>
{%- endmacro %}
flask 项目的开发经验总结的更多相关文章
- Python框架 Flask 项目实战教程
本文目的是为了完成一个项目用到的flask基本知识,例子会逐渐加深.最好对着源码,一步一步走.下载源码,运行pip install -r requirements.txt 建立环境python db_ ...
- 通过VM虚拟机安装Ubuntu server部署flask项目
1. VM安装Ubuntu server 14.04,系统安装完成后,首先安装pip工具方便之后的包安装,此处需先使用 apt-get install update,apt-get install u ...
- flask项目开发中,遇到http 413错误
在flask项目中,上传文件时后台报http 413 Request Entity Too Large 请求体太大错误! 解决的2种方法: 1.在flask配置中设置 MAX_CONTENT_LENG ...
- flask项目部署到阿里云 ubuntu16.04
title: flask项目部署到阿里云 ubuntu16.04 date: 2018.3.6 项目地址: 我的博客 部署思路参考: Flask Web开发>的个人部署版本,包含学习笔记. 开始 ...
- 部署Flask项目到腾讯云服务器CentOS7
部署Flask项目到腾讯云服务器CentOS7 安装git yum install git 安装依赖包 支持SSL传输协议 解压功能 C语言解析XML文档的 安装gdbm数据库 实现自动补全功能 sq ...
- pycharm创建Flask项目,jinja自动补全,flask智能提示
pycharm创建Flask项目,jinja自动补全,flask智能提示 之前一直都是用在idea里创建空项目然后导入,之后就没有各种的智能提示,在选择文类,选择模板之类的地方就会很麻烦. 步骤1:用 ...
- flask 项目基本框架的搭建
综合案例:学生成绩管理项目搭建 一 新建项目目录students,并创建虚拟环境 mkvirtualenv students 二 安装开发中使用的依赖模块 pip install flask==0.1 ...
- windows环境隐藏命令行窗口运行Flask项目
Linux下可以使用nohub来使Flask项目在后台运行,而windows环境下没有nohub命令,如何让Flask项目在windows中在后台运行而不显示命令行窗口呢? 1.写一个.bat脚本来启 ...
- nginx + gunicorn + flask项目发布
程序安装(linux mint) gunicorn安装:pip install gunicorn nginx安装:sudo apt-get install nginx 配置 nginx默认配置信息在/ ...
随机推荐
- Linux内核邮件列表发送和回复格式研究
1.使用的内容格式为[纯文本],这个在国内的客户端已经没有了,大公司只有微软的outlook. 2.回复引用时,使用符号[>]作为标记,且回复的内容不能在最顶部,应该在最下面.参考:http:/ ...
- Microsoft SQL Server,错误: 229 解决方案
今天我在数据库新建一个用户时,碰到了一个奇怪的问题,账号建好了,也指定了该账号上对应的数据库.但是,奇怪的问题出现了,死活不让我新建表,提示如下: 最后,给我找到问题所在了,就是在指定表权限的时候权限 ...
- 数据结构算法C语言实现---序言
期末考试即将到来,打算花两周时间实现书上所有的算法.巩固学习成果(其实之前也没怎么听课......)毕竟考前突击,背背,ppt刷个90+是没多大意义的. 没错,就是下面这本 毕竟书也是借别人的,不抓紧 ...
- alertDialog创建登陆界面,判断用户输入
alertDialog创建登陆界面,需要获取用户输入的用户名和密码,获取控件对象的时候不能像主布局文件那样获得, 需要在onClickListener中获取,代码如下: public boolean ...
- 原生JS中常用的Window和DOM对象操作汇总
一.常用的Window对象操作 Window对象中又包含了document.history.location.Navigator和screen几个对象,每个对象又有自己的属性方法,这里window可以 ...
- django 提示ImportError: cannot import name json_response
from json_response import JsonResponse, json_response as json_resp 使用的语句如上,其实并不是没有安装,只是需要升级一下 pip in ...
- Spring--laobai1
1 spring的概念 (spring:ioc对象工厂+aop.) apache推出的java企业框架,提供了基于ioc的对象工厂.aop功能及其他增强功能. 2 控制反转(ioc):inversi ...
- [NOIP2014] 解方程&加强版 (bzoj3751 & vijos1915)
大概有$O(m)$,$O(n\sqrt{nm})$,$O(n\sqrt{m})$的3个算法,其中后2个可以过加强版.代码是算法3,注意bzoj的数据卡掉了小于20000的质数. #include< ...
- 签名有元程序集 Signed Friend Assemblies
下面的例子演示了创建签名程序集和有元程序集.这就要求两个程序集都是强命名,在下面的例子中,两个程序集都用了同一个秘钥,也可以用不同的秘钥. 1. 生成秘钥, 这个在前面的博客中有说明,生成秘钥文件sn ...
- (新手向)基于Bootstrap的简单轮播图的手机实现
个人电脑里存了不少适合手机欣赏的图片,但是放手机里看是件很占据资源的事.鉴于家里有一台电脑经常开着,正好用来做家庭局域网共享,于是笔者就设想通过一种比较简单环保的思路.通过手机访问电脑内的图片. 首先 ...