
加载应用程序配置有三种方式:
1/从配置对象中加载配置信息from_object
2/从配置文件中加载配置信息
3/从环境变量中加载配置信息
重点掌握第1种,在工作中,我们的项目在启动的时候,需要预先设置一些配置信息,为了方便管理,便于维护,我们将所有的配置信息,封装在一个类中,然后再进行使用,下面是代码的实现过程,大家可以看一下:
# 1.导入Flask类
from flask import Flask
# 2.创建Flask对象接收一个参数__name__,它会指向程序所有的包
app = Flask(__name__)
# 配置对象,里面定义需要给APP添加的一系列配置
class Config(object):
DEBUG = True
# 从配置对象中加载配置
app.config.from_object(Config)
# 3.装饰器的作用是将路由映射到视图函数index
@app.route("/")
def index():
return 'Hello World'
# 4.Flask应用程序实例的run方法,启动WEB服务器
if __name__ == '__main__':
app.run()
提示: 运行测试,在修改代码之后直接保存,会自动重启服务器 通过:app.config.get('DEBUG') 可以获取到配置的信息

methods,它有很多参数,但是我们需要掌握最常用的两个
1.GET是请求,浏览器第一次请求的时候是此get请求
2.POST是提交,这种方式更加的安全,所有的信息是打包进行提交的,我们在防止csrf攻击的时候,就是在post请求的时候,验证csrf_token
具体使用:
@app.route('/demo',methods=['GET','POST'])
def demo():
# 直接从请求中取到请求方式进行返回
return request.method
redirect('路径')路径既可以是外链地址,又可以是视图函数的地址,是字符串的形式.(tip:在使用外链地址的时候,记得在前面加http://)
url_for('函数名',key=value)是反解析,通过视图函数的名称,返回一个地址,经常配合redirect使用
@app.route('/demo1/<int:user_id>')
def demo1(user_id):
return 'hello %d' % user_id
# 重定向
@app.route('/demo5')
def demo5():
# 使用url_for生成指定视图函数所对应的url
return redirect(url_for('demo1',user_id=100))
response=jsonify(dict)
json数据其实是一个字符串,里面是一个字典,如:'{"name":"zhangsan","age":"10"}',要注意的是,json对象的属性名称和字符串必须由双引号引起来,否则会报错.
json和dict相互转换:
# 使用之前需要导入一个类
from flask import json
# 1.json转换成字典
dict = json.loads(json)
# 2.字典转换成json
json = json.dumps(dict)
response=make_response()
自定义状态码:
response.status = 200
自定义响应头:
response.headers["Content-Type"]="application/json"
自定义cookie:
response.set_cookie("name","aaa")

args
是请求信息,地址栏数据 ,问号后面,如www.baidu.com?key=value&key=value
data
是json/xml等,非表单post提交的请求
form
表单post请求提交的
cookies
是存储在浏览器里面的信息
属性 | 说明 | 类型 |
|---|---|---|
data | 记录请求的数据,并转换为字符串,非表单数据 | * |
args | 记录请求中的查询参数 | MultiDict |
form | 记录请求中的表单数据 | MultiDict |
cookies | 记录请求中的cookie信息 | Dict |

请求钩子有四种:我们重点掌握的只有两种:
before_request在每次请求前执行,在该装饰函数中,一旦return,视图函数不再执行
after_request如果没有抛出错误,每次请求后都执行(在执行完视图函数之后会调用,并且会把视图函数所生成的响应传入,可以在此方法中对响应做最后一步统一的处理)

cookie就是网站为了辨别用户的身份,进行会话跟踪而存储在用户本地的数据(通常是经过加密处理的),因为浏览器请求是无状态的,需要cookie才能在下次访问的时候知道上次做了什么,要不然每一次的刷新页面就是一次新的请求,什么记录都没有,好像我们从来没有来过一样,用户体验贼差,有了cookie就知道了用户浏览的状态,比如是否登陆过,之前看过写什么之类的.
这里有一个名词:同源策略,简单的来说,就是不同的网站之间的cookies不能共享
在运用的时候,代码如下:
requestfrom flask import Flask,make_response,request
app = Flask(__name__)
# 设置cookies值
@app.route('/set_cookie')
def set_cookie():
response = make_response("set cookie")
response.set_cookie("name","xiaoyan",10) #10秒的有效期
return response
# 获取cookie值
@app.route('/get_cookie')
def get_cookie():
# 获取cookie的时候是可以根据cookie的键名来获取cookie值的
# name = request.cookies["name"]但是这样错误的时候程序会崩掉,还是用get友好一点
# 可以根据cookie的内容来推荐商品信息
name = request.cookies.get("name")
return "获取到cookie,name is %s" % name
if __name__ == '__main__':
app.run(debug=True)
session是保存在服务器的,对于敏感,重要的信息,建议存储在服务器端,比如用户名,余额等等.
cookie中只保存sessionID,在浏览器发起请求的时候,会连带着cookie,将sessionID一起发送给服务器,服务器根据sessionID提取session的值,每一个用户想服务器请求的时候,都会给其开辟对应的空间保存session信息.
在使用session的时候一定要设置秘钥
from flask import Flask,session
app = Flask(__name__)
# 设置秘钥
app.config["SECRET_KEY"] = "dfdfdfd"
# 设置session
@app.route('/set_session/<path:name>') # path是字符串
def set_session(name):
session["name"]=name
session["age"]="13"
return "set session"
# 获取session的内容
@app.route('get_session')
def get_session():
name = session.get('name')
age = session.get("age")
return "name is %s,age is %s"% (name,age)
if __name__ = '__main__':
app.run(debug=True)
session的存储依赖于cookie,在cookie保存的session编号session编号生成,需要进行加密,所以需要设置secret_key secret_key的作用参考:https://segmentfault.com/q/1010000007295395

上下文:相当于一个容器,保存了Flask程序运行过程中的一些信息
有请求上下文和应用上下文,重点掌握请求上下文
request封装了HTTP请求的内容,针对的是HTTP请求
如user = request.args.get('user')获取的是get请求的参数
session用来记录请求会话中的信息,针对的是用户信息
如session['name'] = user.id可以记录用户信息,
还可以通过session.get('name')

有两种形式,一种是先定义函数,再添加到过滤器列表中,另一种是装饰器的形式.重点掌握第一种.
# 先定义一个函数
def do_listreverse(li):
# 通过原列表创建一个新列表
temp_li = list(li)
# 将新列表进行反转
temp_li.reverse()
return temp_li
# 第一个参数是上面定义的函数名,
# 第二个参数是过滤器的名字
app.add_template_filter(do_listreverse,'lireverse')
有宏/继承/包含
我们需要重点掌握的就是继承:继承指的是将公共部分我们抽取到父模板中,供子类使用的形式
父模板(base.html)中使用多个block组成
{% block top %}
顶部菜单
{% endblock top %}
{% block content %}
正文内容
{% endblock content %}
{% block bottom %}
底部
{% endblock bottom %}
子模板在使用的时候先继承
{% extends 'base.html' %}
{% block content %}
子模板自己的内容
{% endblock content%}
注意:在父模板中时正常的html页面,但是在子模板中直接写extends和block,不需要再写head标签,body标签这些了.
重点掌握的有两个
就是flask中代表当前请求的request对象:
{{ request.url }}
输出:http://127.0.0.1
7.3.2url_for()
url_for 会根据传入的路由器函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不必担心模板中渲染出错的连接
{{ url_for('home) }}
/

点我查看详细知识点
SQLAlchemy是对数据库的抽象,让我们不用直接和SQL语句打交道,而是通过python对象来操作数据库,在舍弃一些性能开销的同时,换来的是开发效率的较大提升.是一个关系型数据库的框架,它提供了高层的ORM和底层的原生数据库操作.
类名称 | 类属性 | 类的对象 |
|---|---|---|
数据库表名 | 数据库的字段 | 数据库表中的一行一行的数据 |
1/我们在定义模型的时候要继承的类是db.Model
2/添加外键的时候要添加在多方
3/添加关系的时候添加在一方
class Role(db.Model):
...
# 关键代码
添加关系
us = db.relationship('User',backref='role',lazy='dynamic')
...
class User(db.Model):
...
# 添加外键
role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
其中relationship描述了Role和User的关系 第一个参数为对应参照的类"User" 第二个参数backref为类User,反向引用属性,即给多方指定内容访问一方 第三个参数lazy决定了什么时候SQLAlchemy从数据库中加载数据
第四个参数secondary:指定多对多关系中关系表的名字
增加:
db.session.add()
db.session.add_all()
删除:
db.session.delete()
修改:
user.name = xiaoyan
提交:
db.session.commit()
回滚:
db.session.rollback()
模型类.query.过滤器.执行器
12条语句:
1/查询所有用户数据:
User.query.all()
2/查询有多少个用户:
User.query.count()
3/查询第一个用户
User.query.all()[0]
4/查询id为4的用户(3种方式)
User.query.get(4)
User.query.filter_by(id=4).fitst()
User.query.filter(User.id==4).first()
5/查询名字结尾字符为g的素哟有数据[开始/包含]
User.query.filter(User.name.endswith('g')).all()
User.query.filter(User.name.startswith('g')).all()
User.query.filter(User.name.contains('g')).all()
6/查询名字不等于wang的所有数据[2种方式]
User.query.filter(User.name!='wang').all()
from sqlalchemy import not_
User.query.filter(not_(User.name=='wang')).all
7/查询名字和邮箱都以li开头的所有数据[2种方式]
User.query.filter(User.name.startswith('li'),User.email.startswith('li')).all()
from sqlalchemy import and_
User.query.filter(and_(User.name.startswith('li'),User.email.startswith('li'))).all()
8/查询password是123456或者email以itheima.com结尾的所有数据
from sqlalchemy import or_
User.query.filter(or_(User.password=='123456',User.email.endswith('itheima.com'))).all()
9/查询id为[1,3,5,7,9]的用户列表
User.query.filter(User.id.in_([1,3,5,7,9])).all()
10/查询name为liu的角色数据
user = User.query.filter(User.name=='liu').first()
role = Role.query.filter(Role.id==user.role_id).first()
11/查询所有用户数据,并以邮箱排序
User.query.order_by(User.email).all()升序
User.query.order_by(User.email.desc()).all()降序
12/每页3个,查询第2页的数据
paginate = User.query.paginate(page,per_page,Error_out)
paginate = User.query.paginate(2,3,False)
page哪一页
per_page每页多少条数据
Error_outFalse查不到不报错
数据库的迁移配合Flask_script使用
命令:
创建文件夹(此过程,只执行一次):
python xxx.py db init
生成指定版本迁移文件(每次改变的时候都需要执行):
python xxx.py db migrate -m 'sss'
升级或者降级:
python xxx.py db upgrade/downgrade[version]
查看最新/当前/历史版本:
python xxxx.py db show/current/history
点我查看详细知识点
将项目模块化的工具:
特点:
1/有自己的静态文件,模板文件
2/如果有静态文件,可以配置url_prefix去访问当前蓝图目录下的静态文件
3/蓝图本质上实现的原理(从源代码中看)
使用步骤:
1/创建蓝图对象(Blueprint)
admin = Blueprint('admin',__name__)
2/使用蓝图装饰函数
@admin.route('/')
def admin_home():
return 'admin_home'
3/将蓝图注册到app中(register_blueprint)
app.register_blueprint(admin,url_prefix='/admin')

优质文章推荐:
公众号使用指南
redis操作命令总结
前端中那些让你头疼的英文单词