java中的接口是类吗
411
2022-09-05
flask 项目的开发经验总结(flask python)
已经开发了几个flask项目, 是时候总结一下了, 这里涉及到项目源码的组织和源码示例.
=========================
目录结构
=========================
考虑到项目的扩展性, 采用 blueprint 进行组织. 假设 flaskapp 为根目录, 主要的程序放在 app 包中, 除了后台代码, 在app目录下还有templates/static/子目录. 为了重用, 最好的形式是一个建立 boilerplate 项目.
主要参考文档为:
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 等等. 更多的配置项见 作为整个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
---------------------
子应用级别的单元,
----------------------
称为subapp或称为module, 目录采用复数形式
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 appapp.run()
------------------------------
config.py
------------------------------
config.py 存储一些db的 connection 配置, 以及Flask SECRET_KEY 等等. 更多的配置项见 -*- coding: utf-8 -*- from __future__ import absolute_importimport osfrom datetime import timedelta_basedir = os.path.abspath(os.path.dirname(__file__))DEBUG = TrueSECRET_KEY = os.urandom(24)PERMANENT_SESSION_LIFETIME=timedelta(seconds=24*60*60)CSRF_ENABLED = TrueCSRF_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_importfrom flask import Flask, g, render_template, send_from_directoryimport osimport 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 objectapp.config.from_pyfile(configPy)#app.debug=True #change some attribute after load configurationflask_sqlalchemy_used=True # 如果使用Flask-SQLAlchemy了db = SQLAlchemy(app) #create a db (SQLAlchemy) object from our app objectlogin_manager = LoginManager(app) #create a LoginManager Object from our app object#add our view as the login view to finish configuring the LoginManagerlogin_manager.login_view = "users.login_view"#register the users module blueprintfrom app.users.views import mod as usersModuleapp.register_blueprint(usersModule)#register the tickets module blueprintfrom app.tickets.views import mod as ticketsModuleapp.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_requestdef before_request(): """Make sure we are connected to the database each request.""" if not flask_sqlalchemy_used: g.db = connect_db()@app.teardown_requestdef 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_importfrom flask import Blueprint, render_template, flash, redirect, session, url_for, request, gfrom flask.ext.login import login_user, logout_user, login_requiredfrom app import app, db, login_managerfrom forms import LoginForm, RegistrationFormfrom app.users.models import Usermod = Blueprint('users', __name__) #register the users blueprint module@login_manager.user_loaderdef 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. 内容摘自 macro form_field(field) -%} {% set with_label = kwargs.pop('with_label', False) %} {% set placeholder = '' %} {% if not with_label %} {% set placeholder = field.label.text %} {% endif %}
{{ field.description|safe }}
{% endif %}版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~