-基于python开发web的微框架
-轻量级框架
-并不是说不适用于大型项目
-指的是为开发者做了很少的选择
-内置两大核心模块
-jinja2模板引擎
-Werkzurg
-WSGI工具集
from flask import Flask,abort
app=Flask(__name__)
@app.route('/')
def hello():
return 'hello flask'
if __name__ == '__main__':
app.run()
-flask中的调试器拥有保护功能
-PIN
-如果需要在页面中进行调试,需要输入PIN码进行确认
-系统级
-/etc/envirtonment
-/etc/profile
-用户级
-/.bashrc
-临时级
-在窗口中直接export
-可以添加flask脚本的扩展库
-添加命令行参数
-使用
-安装
-初始化
-使用app构建manager对象
-调用
-runserver
-使用的时候容易出现循环引用的问题
-使用懒加载的方法
-使用函数调用的形式进行加载
manage.py
from flask_script import Manager
from app import create_app
app=create_app()
manager=Manager(app=app)
if __name__ == '__main__':
manager.run()
init.py
from flask import Flask
from app.views import init_route
def create_app():
app=Flask(__name__)
init_route(app)
return app
views.py
def init_route(app):
@app.route('/')
def hello_world():
return 'hello world'
@app.route('/hello/')
def hello():
return 'hello nimei!'
-使用新方案解决
-蓝图
-代表一种规划
-路由的规划
-flask-blueprint
-使用过程
-安装
-初始化
-需要创建蓝图对象
-name
-导入名字__name__
-需要使用app进行初始化
-注册在app上
-使用
-和flask对象差不多
-直接作为装饰器用来注册路由
init.py
from flask import Flask
from app.views import init_view
def create_app():
app=Flask(__name__)
init_view(app=app)
return app
views/init.py
from .first_blue import blue
from .second_blue import second
from .third_blue import third
def init_view(app):
app.register_blueprint(blue)
app.register_blueprint(second)
app.register_blueprint(third)
views/first_blue.py
from flask import Blueprint
blue= Blueprint('blue',__name__)
@blue.route('/')
def index():
return '我是蓝图的主页'
views/second_blue.py
from flask import Blueprint
second= Blueprint('second',__name__)
@second.route('/second/')
def hello():
return 'second blue'
views/third_blue.py
from flask import Blueprint
third= Blueprint('third',__name__)
@third.route('/third/')
def hello():
return 'hi,third blue'
-web开发中大多数情况都是关系型数据库
-ORM
-SQLAlchemy
-flask-sqlalchemy
-安装
-初始化
-需要使用app进行SQLAlchemy对象创建
-使用懒加载方法 init_app方法搞定
-SQLALCHEMY_DATABASE_URI
-连接数据库的路径
-URI格式
-数据库+驱动://用户名:密码@主机:端口/具体哪一个库
-SQLALCHEMY_TRACK_MODIFICATIONS = False
-将来被添加进来的一个特性
-默认是False
-使用
-定制模型
-继承自Model
-创建字段
-创建库,创建表
-库需要手动创建
-表
-SQLAlchemy对象.create_all
-删除.drop_all
-不能差量更新
-数据操作
-存储
-创建对象
-SQLAlchemy对象.session.add()
-添加完成还要进行commit()
-迁移插件
-在flask中像django中一样进行模型迁移
-使用流程
-安装
-初始化
-使用app和db进行初始化
-可以使用懒加载方法
-使用
-flask db 指令
-init
-migrate
-upgrade
-结合flask-script使用
-在manager添加一个管理指令
-manager.add_command(‘db’,MigrateCommand)
-python manage db 指令
-原版
-helloflask.py
-改良
-三阶改装
-manage.py
-项目管理文件
-app
-init
-初始化文件
-settings
-config
-全局项目配置
-ext
-extension扩展库
-除了和路由相关
-views
-apis
-路由,视图函数
-models
-定制模型
-开发环境
-开发人员使用
-测试环境
-测试人员使用
-演示环境
-给产品看的
-做演习
-生产环境,线上环境
-真实环境
-给用户看的
-路由
-路由参数获取
-<>
-语法converter:name
-converter
-int
-float
-string
-以/作为结尾
-path
-从path修饰开始,后面的东西都是我们的
-/没有作用了
-视图函数
-默认支持GET,HEAD,OPTIONS
-其余请求不支持
-想支持某种请求,需要手动注册
-Request
-url
-完整请求地址
-base_url
-去掉get参数的url
-host_url
-只有主机和端口号的url
-path
-路由中的路径
-method
-请求方法
-remote_addr
-请求的客户端地址
-args
-请求参数
-query_string
-query_params
-get请求参数
-它并不是get专属,所有请求都能获取这个参数
-form
-表单数据
-post请求参数
-直接支持put,patch
-ImmutableMultiDict
-args和form都是这个类型
-dict子类
-files
-headers
-cookies
-flask中的cookie默认对中文进行了处理,直接可以使用中文
#response
-创建response的三种方式
-直接返回字符串
-make_response
-直接构建response
-参数设置
-内容
-状态码
-render_template
-帮助把模板变成html字符串
-重定向
-redirect
-反向解析 url_for
-终止处理
-abort
-本质上就是一个exception
-HttpException
-子类指定两个属性即可实现
-code
-description
-异常捕获
-可以提升程序交互
-让程序变得友好
-注册errorhandler
#session
-服务端会话技术
-数据存储在服务器
-key-value
-flask中
-将session存储在cookie中
-对数据进行了序列化
-还进行了base64
-还进行了zlib压缩
-还传递了hash
-session时间是31天
-实现了服务端session
-将数据存储服务端,将数据对应的key存储在cookie中
-G
-跨函数传递数据
-间接传递数据
-Config(app)
-获取配置信息
-python current_app
-一定是在项目启动之后
-模板路径默认在flask(app)创建的路径下
-如果想自己指定模板路径
-在flask创建的时候,指定template_folder
-在蓝图创建的时候,也可以指定
-蓝图指定此蓝图统一前缀 /xx
-模板中使用反向解析和在python代码中一样
-url_for
-静态资源在flask中是默认支持的
-默认路径在和flask同级别的static中
-如果想自己指定模板路径
-在flask创建的时候,指定static_folder
-在蓝图创建的时候,也可以指定
-静态资源也是有路由的
-endpoint是static
-参数有一个filename
-{ {url_for(‘static’,filename=‘xxx’)}}
-从django中借鉴的
-样式基本一致
-使用方式更简单
-安装
-使用app初始化
-用来封装数据操作
-ORM
-约束
-主键约束
-外键
-autoincrement
-index
-unique
-nullable
-数据交互CRUD
-数据创建
-创建对象,通过db.session
-add
-add_all
-commit
-更新
-基于查询
-查出数据进行修改,修改完再次存储
-删除
-基于查询
-db.session.delete()
-db.session.commit
-查询
-获取单个对象
-first order_by(’-xx’).first
-get 只能给主键值
-get_or_404
-获取结果集
-all
-特殊,特列
-列表
-filter
-BaseQuery对象
-str__输出的是这个对象数据的SQL
-条件
-类名.属性名.魔术方法(临界值)
-类名.属性名 操作符运算符 临界值
-offset和limit不区分顺序
-order_by调用必须放在offset和limit之前
-filter_by
-用在级联数据上
-条件语法精准
-字段=值
-级联数据
-获取
-手动实现获取
-使用关系 relationship进行级联查询
-反向引用
-关系
-1:1
-1:M
-M:N
-筛选在flask-sqlalchemy中,all如果使用只能放在最后
-分页器
-paginate
-默认可以接收两个参数
-page
-per_page
-pagenation
-逻辑运算
-and
-or
-not_
-模型信息指定
-表名
-tablename
-模型继承
-默认继承并不会报错,它会将多个模型的数据映射到一张表中,导致数据混乱,不能满足基本使用
-抽象的模型是不会在数据库中产生映射的
-abstract=True
-文档
-flask-sqlalchemy
-sqlalchemy
-项目中数据库优化
-怎么连接
-连接多少个
-django和flask
-默认都是有数据库连接池的
-维护一定数量的数据库连接
models.py
from app.ext import db
class News(db.Model):
id=db.Column(db.Integer,primary_key=True,autoincrement=True)
n_title=db.Column(db.String(32))
n_content=db.Column(db.String(256))
views.py
from flask import Blueprint
from app.models import News
blue=Blueprint('blue',__name__)
@blue.route('/')
def index():
return 'index'
@blue.route('/addnews/')
def add_news():
news=News()
news.n_title='胡歌%d'% random.randrange(10000)
news.n_content='福利社会%d' random.randrange(10000)
db.session.add(news)
db.session.commit()
return 'add success'
@blue.route('/getnews/')
def get_news():
news_list=News.query.all()
news_content=render_template('news_content.html',news_list=news_list)
encode_content=base64.standard_b64encode(news_content.encode('utf-8')).decode('utf-8')
add_content_encode_content='加密字符串'+encode_content+'加密字符串'
add_content_twice=base64.standard_b64encode(add_content_encode_content.encode('utf-8')).decode('utf-8')
return render_template('newlist.html',news_content=add_content_twice)
news_content.html
<ul>{
% for news in news_list %}<li>{
{
news.n_content}}</li>{
% endfor %}</ul>
newlist.html
需要加载相应的js进行解密
<h2>news</h2>
<script type='text/javascript'>
document.write('{
{news_content|safe}}');
</script>
-面向切面编程
-动态介入请求流程
-before_request
-after_request
models.py
from Werkzurg.security import check_password_hash,generate_password_hash
class Student(db.Model):
id=db.Column(db.Integer,primary_key=True,autoincrement=True)
s_name=db.Column(db.String(16),unique=True)
_s_password=db.Column(db.String(256))
s_phone=db.Column(db.String(16))
@property
def s_password(self):
raise Exception("Error Action:password can't be access")
@s_password.setter
def s_password(self,value):
self._s_password=generate_password_hash(value)
def check_password(self,password):
return ckeck_password_hash(self._s_password,password)
views.py
@blue.route('/student/register/',methods=['GET','POST'])
def student_register():
if request.method=='GET':
return render_template('student_register.html')
elif request.method=='POST':
username=request.form.get('username')
password=request.form.get('password')
student=Student()
student.s_name=username
student.s_password=password
db.session.add(student)
db.session.commit()
return 'register success'
@blue.route('/student/login/',methods=['GET','POST'])
def student_login():
if request.method=='GET':
return render_template('student_login.html')
elif request.method=='POST':
username=request.form.get('username')
password=request.form.get('password')
student=Student.query.filter(Student.s_name.__eq__(username)).first()
if student and student.check_password(password):
return 'login success'
flash('用户名或密码错误')
return redirect(url_for('blue.student_login'))
student_register.html
<form action='{
{url_for('blue.student_register')}}' method='post'>
<span>username:</span><input type='text'> name='username' placeholder='please input username'>
<br>
<span>password:</span><input type='password'> name='password' placeholder='please input password'>
<br>
<button>register</button>
student_login.html
{
% for message in get_flashed_messages() %}
<li>{
{
message }}</li>
{
% endfor %}
<form action='{
{url_for('blue.student_login')}}' method='post'>
<span>username:</span><input type='text'> name='username' placeholder='please input username'>
<br>
<span>password:</span><input type='password'> name='password' placeholder='please input password'>
<br>
<button>login</button>
-邮箱
-异步发送邮件
-在邮件中包含激活地址
-激活地址接收一个一次性的token
-token是用户注册的时候生成的,存在了cache中
-key-value
-key token
-value 用户的一个唯一标识
-短信
-同步操作
-
pip install flask-mail 安装第三方依赖库
from flask_mail import Mail
mail=Mail()
app=Flask(__name__)
mail.init_app(app)
settings.py
MAIL_SERVER='smtp.163.com'
MAIL_PORT=25
MAIL_USERNAME=邮箱地址
MAIL_PASSWORD=授权码
MAIL_DEFAULT_SENDER=MAIL_USERNAME
views.py
@blue.route('/sendmail/')
def send_mail():
msg=Message('Flask Email',recipients=['[email protected]',])
msg.body='hello'
msg.html='welcome to my site
'
mail.send(message=msg)
return 'send success'
-quick start
apis.py
from flask_restful import Api,Resource
api=Api()
def init_api(app):
api.init_app(app)
class HelloResource(Resource):
def get(self):
return {
'msg':'hello api'}
api.add_resource(HelloResource,'/hello/')
不要忘记注册init_api(app)
-进阶
init.py
from flask_restful import Api
from app.apis.user_api import UsersResource,UserResource
api=Api()
def init_api(app):
api.init_app(app)
api.add_resource(UsersResource,'/users/')
api.add_resource(UserResource,'/user//' )
user_api.py
from flask_restful import Resource
class UsersResource(Resource):
def get(self):
return {
'msg':'users list'}
class UserResource(Resource):
def get(self,id):
return {
'msg':'user%d ok' %d}