大家看到这篇博客时,相信大家就内心就已经选择了flask,那对它的优劣,我这里就不多说了
一、python虚拟环境的安装
1.由于flask不同版本可能存在不兼容的问题,可以用虚拟环境解决上述问题
2.安装虚拟环境:pip install virtualenv
3.开辟新的虚拟环境:virtualenv {virtualenv-name}
4.激活虚拟环境:
{类linux}:source {虚拟环境目录}/bin/activate
{windows}: 直接进入到虚拟环境的目录,然后执行activate
退出虚拟环境:deactivate
二、flask安装
pip install flask 如果需要安装到虚拟环境里,就必须进入虚拟环境里进行安装
三、debug模式
1.app.run(debug=True) 当前项目模式为debug模式
2.debug模式两大好处:
程序出现问题时,页面会显示错误信息和出错位置
修改项目中python文件(.py),程序会自动加载,不用手动重启。
四、使用配置文件
1.新建config配置文件
2.到处主运行文件中,APP加载app.config.from_object(config)
五、URL传参到视图
1.url中的参数命名用<变量>
2.视图函数要用url定义的变量名进行接收
@app.route('/articles/<id>')
def article(id):
return '==>%s'%id
六、url反转:url_for 你就想象成 这个和django中的url别名效果差不多
只不过这里直接用视图函数名作为映射标志
即通过字符串形式的视图函数,可获取到请求的url
在页面重定向时会用到url反转
在模板中也能使用url反转
@app.route('/')
def index():
print(url_for("my_list"))
print(url_for('article',id='456'))
return 'Hello World!'
@app.route('/articles/<id>/')
def article(id):
return '==>%s'%id
@app.route('/list/')
def my_list():
return 'home'
七、模板渲染和参数
1.模板文件定义在templates下
2.视图如果要渲染模板,需要导入render_template
3.渲染变量,可以关键字传入到前端,也可以字典传入
@app.route('/home/')
def home():
return render_template('index.html',name='seven')
八、模板语言
1.由于flask使用的jinjia2模板渲染引擎,所以字典、列表取值支持中括号,也支持.
2.flask模板过滤器:只作用于模板的变量,经过特定处理后才显示出来
{{ a|default(1) }} 不存在时设定的默认值
{{ b|length }} 返回变量的长度
<h1>欢迎您{{ name|default('alex') }}</h1>
<h2>{{ li|length }}条</h2>
3.继承:{% extends ... %} {% block ... %}{% endblock %}
4.url加载和静态文件加载
{{ url_for('login') }}
{{ url_for('static','js/index.js') }}
九、SQLAlchemy操作数据库
1.初始化:import flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
2.数据库配置:配置文件中,定义好数据各变量后,按照
dialect+driver://username:password@host:port/database?charset=utf8
拼接好字符串,并赋值给flask指定变量SQLALCHEMY_DATABASE_URI
3.创建表
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.String(100),nullable=False)
content = db.Column(db.Text,nullable=False)
4.增删改查
见代码
5.外键
外键绑定:
author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
上述过程也只是在表上实现了外键关联,如果要正反向查询还要:
#正向访问author 反向访问articles
author = db.relationship('User',backref=db.backref('articles'))
详见代码
十、flask_script
flask_script的作用是可以通过命令行的形式来操作flask
例如:通过命令跑一个开发版本的服务器、设置数据库、定时任务器
pip install flask_script
实现方式:利用flask_script的manager对象提供的命令行装饰器
装饰某个函数,而函数实现你想要的过程
函数名即命令,比如在主文件中的 python manage.py runserver
其中runserver就是函数名
详见代码
十一、models解耦和解决循环引用
分开models的目的:为了让代码更加方便的管理
models引用db和主运行文件db加载app的循环引用问题:
把db放在一个单独的文件中,切断循环引用线条
db重加载APP:db.init_app(app)
注意flask里APP在上下文的问题
with app.app_context():
db.create_all()
十二、flask_migrate表刷新
问题:使用db.create_all,如果后面有修改表结构(比如增加字段),
不会自动映射到数据库,必须删除表然后创建才可以,这明显不符
实际应用场景,那么migrate结合flask_script命令就能实现不删表
就能同步数据库
安装: pip install flask_migrate
#这里命令同步表 就要在这里导入模型
from models import Article,User
manager = Manager(app)
#1.要用flask_migrate 必须绑定app和db
migrate = Migrate(app,db)
#2.把MigrateCommand命令添加到manager中
manager.add_command('db',MigrateCommand)
#模型 --> 迁移文件 --> 表
#init 初始化迁移环境
#migrate 模型生成迁移文件
#upgrade 迁移文件生成表
十三、flask session
工作原理:把session加密存在客户端的cookie里
操作session:
增: session['xxx'] = 'ooo'
查: session['xxx'] session.get('xxx')
改: session['xxx'] = 'hahaha'
删: session.pop('xxx') del session['xxx'] session.clear()
注意操作session要配置文件里设置secret_key的东西
SECRET_KEY = os.urandom(24) #设置一个随机24位的字符串
还要注意 重启服务时,secret_key随机变化对session的影响
十四、获取请求参数
get请求:flask.request.args 前端 {{ url_for('login',q='11') }}
post请求: flask.request.form 后端路由装饰器 @app.route('/login/',methods=['GET','POST'])
请求类型:flask.request.method
执行视图函数前,钩子函数 装饰器@app.before_request装饰钩子函数
代码
# -*- coding:utf-8 -*- import os DEBUG = True #database config # dialect+driver://username:password@host:port/database?charset=utf8 DIALECT = 'mysql' DRIVER = 'mysqldb' USERNAME = 'root' PASSWORD = 'xx,,' HOST = '127.0.0.1' PORT = '3306' DATABASE = 'flask_db' SQLALCHEMY_DATABASE_URI = '{}+{}://{}:{}@{}:{}/{}?charset=utf8'.format( DIALECT,DRIVER, USERNAME,PASSWORD, HOST,PORT, DATABASE) SQLALCHEMY_TRACK_MODIFICATIONS = False #操作session时,需要设置这么一个key SECRET_KEY = os.urandom(24) #设置一个随机24位的字符串
# -*- coding:utf-8 -*- from flask_script import Manager db_manager = Manager() @db_manager.command def init(): print('数据库初始化完成') @db_manager.command def migrate(): print('数据库迁移成功')
# -*- coding:utf-8 -*- #model分流 切断循环引用 中转站 from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy()
# -*- coding:utf-8 -*- from second_flask import app from flask_script import Manager from db_scripts import db_manager from flask_migrate import Migrate,MigrateCommand from exchange import db #这里命令同步表 就要在这里导入模型 from models import Article,User manager = Manager(app) #1.要用flask_migrate 必须绑定app和db migrate = Migrate(app,db) #2.把MigrateCommand命令添加到manager中 manager.add_command('db',MigrateCommand) #模型 --> 迁移文件 --> 表 #init 初始化迁移环境 #migrate 模型生成迁移文件 #upgrade 迁移文件生成表 @manager.command #主文件命令:python manage.py runserver def runserver(): print('服务器跑起来了.....') # manager.add_command('db',db_manager) #引入命令:python manage.py db init if __name__ == '__main__': manager.run()
# -*- coding:utf-8 -*- from exchange import db class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db.String(100),nullable=False) tags = db.Column(db.String(32),nullable=False) class Article(db.Model): __tablename__ = 'article' id = db.Column(db.Integer,primary_key=True,autoincrement=True) title = db.Column(db.String(100),nullable=False) content = db.Column(db.Text,nullable=False) author_id = db.Column(db.Integer,db.ForeignKey('user.id')) #正向访问author 反向访问articles author = db.relationship('User',backref=db.backref('articles'))
# -*- coding:utf-8 -*- from flask import Flask,url_for,redirect,render_template,session,request # from flask_sqlalchemy import SQLAlchemy from exchange import db # from models import Article,User import config app = Flask(__name__) app.config.from_object(config) # db = SQLAlchemy(app) db.init_app(app) # with app.app_context(): # db.create_all() # class User(db.Model): # __tablename__ = 'user' # id = db.Column(db.Integer,primary_key=True,autoincrement=True) # username = db.Column(db.String(100),nullable=False) # # class Article(db.Model): # # __tablename__ = 'article' # id = db.Column(db.Integer,primary_key=True,autoincrement=True) # title = db.Column(db.String(100),nullable=False) # content = db.Column(db.Text,nullable=False) # author_id = db.Column(db.Integer,db.ForeignKey('user.id')) # # #正向访问author 反向访问articles # author = db.relationship('User',backref=db.backref('articles')) #可以用于验证数据库项有没有配置对 # db.drop_all() # db.create_all() @app.route('/') def index(): redirect_url = url_for('login') return redirect(redirect_url) return u'您已经登录' @app.route('/login/') def login(): return u'请登录' @app.route('/articles/<id>/') def article(id): return '==>%s'%id @app.route('/home2/') def home2(): # user = User(username='seven') # db.session.add(user) # db.session.commit() # article1 = Article(title='title',content='content') # # article1.author = User.query.filter(User.id == 1).first() # db.session.add(article1) # db.session.commit() #正向 # article2 = Article.query.filter(Article.title == 'title').first() # print(article2.author.username) # article3 = Article(title='aaa',content='ddd',author_id=1) # db.session.add(article3) # db.session.commit() # # #反向查 # u = User.query.filter(User.id == 1).first() # for article in u.articles: # print(article.title) return 'home2' @app.route('/home/') def home(): #增加 # article_one = Article(title='aaa',content='bbb') # db.session.add(article_one) # db.session.commit() #查 # ret = Article.query.filter(Article.title == 'aaa').first() # print(ret.title) # print(ret.content) #改 # article_obj = Article.query.filter(Article.title == 'aaa').first() # article_obj.content = 'shift' # db.session.commit() #删 # article_obj = Article.query.filter(Article.content == 'shift').first() # db.session.delete(article_obj) # db.session.commit() return 'the data is update finished' @app.route('/add/') def add(): session['username'] = '123' print(session['username']) return 'add' @app.route('/operation/') def operation(): print(session.get('username')) session.pop('username') print(session.get('username')) return 'operation' @app.route('/operation2/') def operation2(): print(session.get('username')) session.clear() print(session.get('username')) return 'operation2' if __name__ == '__main__': app.run()