Flask笔记

官方文档: http://flask.pocoo.org/docs/0.11/
中文文档: http://docs.jinkan.org/docs/flask/

HTTP协议:

  1. 请求
    • 请求行
    • 请求头
    • 请求体
  2. 响应
    • 响应行

      • HTTP / 1.1 200 OK

      • 响应状态:

      • 200:响应成功
      • 302:重定向
      • 304:资源未更新
      • 404:资源不存在
      • 500:服务器内部错误

  • 键值对:说明

​ Content-Type:文件类型 text/html image/jpeg application/json text/xml

  • 响应体

1.定义正则:

1.导包
from werkzeug.routing import BaseConverter
2.创建正则类,重写__init__方法,并调用父类方法
class XXXX(BaseConverter):
    def __init__(self, url_map, *args):                                                              super(XXXX,self).__init__(url_map)
        self.regex = args[0]
3.添加至app
# 创建Flask对象
app = Flask(__name__)
app.url_map.converters['re'] = XXXX
# 视图入口
if __name__ == "__main__":
    app.run(debug=True)  # 调试模式

2.传参

  • 在@app.route(‘/<>’)路由中添加可变参数: <id>
  • 规定参数类型:<int:id>
  • 引用正则:<re('[a-z]'):id>

3.返回JSON数据

  1. 导入json数据包
  2. 调用返回:json.jumps(json-data)

4.状态码

def ret():
    return 'data',  200
# 抛出异常,404代表异常类型
def abort_test();
    abort(404)
    return 'data'  # 可以返回字符串,Flask自动封装为响应对象
自定义状态码视图
@app.errorhandler(500)  # 注册状态码处理函数
def error_test(value):
    return '服务器忙...'

5.上下文对象(request.response)

  1. request

  2. sesion

  3. current_app

  4. g

    (response)

Flask 封装request和response为全局对象

request方法:

方法 解释
args 一个包含解析过的查询字符串( URL 中问号后的部分)内容的 MultiDict
form 一个包含解析过的从 POST 或 PUT 请求发送的表单对象的 MultiDict 。请注意上传的文件不会在这里,而是在 files 属性中
value 一个包含 form 和 args 全部内容的 CombinedMultiDict
cookies 一个包含请求中传送的所有 cookie 内容的 dict
headers 进入请求的标头存为一个类似字典的对象
files 一个包含 POST 和 PUT 请求中上传的文件的 MultiDict. 包含save()方法
method 当前请求的 HTTP 方法
如下参考完整url信息 http://www.example.com/myapplication/page.html?x=y
path /page.html
script_root /myapplication
base_url http://www.example.com/myapplication/page.html
url http://www.example.com/myapplication/page.html?x=y
url_root http://www.example.com/myapplication/

response方法:

方法 解释
headers Headers 对象用于设置响应的头信息
status 用于设置响应状态描述
status_code 整数,用于设置响应状态码
mimetype 用于设置响应的MIME类型
set_cookie() 设置cookie

示例:

response = make_response('显示文字')  # 创建response对象
response.set_cookie(key, value)  # 设置cookie

request.headers.get('User-Agent')  # 获取请求头中内容

session['key'] = value  # 设置session
session.get('key')  # 获取session

6.应用上下文current_app和变量g

current_app 可以获取当前app所在环境信息(ip,内存等)

current_app.name  # 获取应用名称
current_app.test_value='value'  # 利用应用上下文存取变量
g.name='abc'  # 临时性全局变量

*手动创建应用上下文:应用上下文只存在于当前主线程中,额外创建的子线程中需要手动创建

with app.app_context():
    other_code_for_you

7.Flask扩展包

  • Flask-SQLalchemy:操作数据库;
  • Flask-Migrate:管理迁移数据库;
  • Flask-Mail:邮件;
  • Flask-WTF:表单;
  • Flask-Bable:提供国际化和本地化支持,翻译;
  • Flask-Script:插入脚本;
  • Flask-Login:认证用户状态;
  • Flask-OpenID:认证;
  • Flask-RESTful:开发REST API的工具;
  • Flask-Bootstrap:集成前端Twitter Bootstrap框架;
  • Flask-Moment:本地化日期和时间;

8.Flask_script扩展

from flask import Flask
from flask_script import Manager  # 导入
app = Flask(__name__)
manager = Manager(app)  # 注册
@app.route('/')
def index():
    return '床前明月光'
if __name__ == "__main__":
    manager.run()  # 使用

9.Flask-Script插件

添加管理功能:

pip install Flask-Script # 安装

from flask_script import Manager
app = Flask(__name__)
...
manager = Manager(app)
...
manager.run()

python app.py runserver # 运行

测试的命令行环境(调试):

python app.py shell
...  # 修改调试上下文(app.app_context()返回current_app)
...  # app.test_request_ctx()

… 上下文对象存储于栈结构中:先进后出,后进先出

10.模板

  • 模板语言

    • 代码块: {{ }}

    • 逻辑代码: {% %} 也可以使用过滤器

      • {{ loop.index }} # 返回循环索引,从1开始
      • {{ loop.cycle('1', 'a', 'c') }} # 返回cycle中作为索引
    • 禁止解析: {% raw %} <script>js处理</script> {% raw %}

    • 过滤器: {{ variable | filter_name(*args) }} # *args在没有条件的情况下可以省略

      示例:

      • {{ 111 | float }}
      • {{ 111.11 | int }}
      • {{ [python , flask] | join(',')}}
      • {{ '123' | length }}
      • {{ 3.1415 | round(2) }} # 四舍五入
      • {{ 4.22 | round(1, 'common') }} # 四舍五入
      • {{ 4.28 | round(1, 'floor') }} # 舍位
      • {{ 4.22 | round(1, 'ceil') }} # 进位
      • {{ {'key': 'value'} | tojson }} # json输出
      • {{ 'abcdefg' | truncate(3, True) }} # 截取,True代表包含空格
      • {{ False_args | default('Treu_args, True') }} # 变量为假时,替换为default值
      • {{ '%s is %d' | format('name',17) }} # 格式化输出
      • {{ ' hello world ' | trim }} # 去掉首尾空格
      • {{ '<em>hello</em>' | striptags }} # 渲染前去掉HTML标签
      • title upper lower capitalize等
    • 自定义过滤器

      app.jinjia_env.filters['key'] = filter_function # 注册过滤器函数

  • 模板渲染

    模板文件放在项目根目录下templates目录下

    • render_template('index.html')
  • 模板传参

    • render_template('index.html', name=name, pwd=pwd)

11.宏

实现HTML代码重用(类似于代码公共部分抽取,继承)

{% macro func(name,label,value='',type='text') %}
    <input type="{{type}}" name="{{name}}"
            value="{{value|escape}}" class="form-control">
{% endmacro %}

调用:

func(name, 'username') # 当前文件调用

封装为文件:

{% macro function() %}
    <div class="form-group">
        <input type="{{type}}" name="{{name}}"
            value="{{value|escape}}" class="form-control">
    </div>
{% endmacro %}

其他文件调用:

{% import 'macro.html' as func %}
{% func.function() %}

12.模板继承

调用父类模板内容

{% block content %}
{% super() %}
... // 自定义内容
{% endblock %}

13.Flask 特有变量和函数

url_for() # 获取视图函数对应的url

redirect(url_for('views_function')) # 重定向(发送两次请求,地址栏改变)

设置: app.config['aaa']='xxx' 获取: {{config.aaa}} # 作为配置文件信息使用

设置: session['aaa']='xxx' 获取: {{session.get('aaa')}}

flash('a')=b  # 应用中设置


{%for message in get_flashed_messages()%}
    {{message}}  // 获取输入框提示信息等
{%endfor%}

14.Form

1.WTF–简化form生成以及验证过程

常用字段:

常用字段

表单内容验证函数:

表单验证函数

from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField
from wtforms.validators import DataRequired,EqualTo

class Login(FlaskForm):
​   username = StringField(lable='用户名', validators=[DataRequired()])
​   password = PasswordField(label='密码', validators=[DataRequired(),                    EqualTo('ps2','err')])
​   submit = SubmitField('提交')
# u(原生字符)可以使用如下代码替代:
    app.config['SECRET_KEY'] = 'abc'  # 非对称加密公钥

@app.route('/register')
def register():
    form = login()  # 创建对象
    return render_template('register.html', form=form)
<form method="post" action="">
    {{ form.csrf_token() }}
    {{ form.username.label }}
    <p>{{ form.us }}</p>
    {{ form.password.label }}
    <p>{{ form.ps }}</p>
    <p>{{ form.submit() }}</p>
    {% for x in get_flashed_messages() %}
        {{ x }}
    {% endfor %}
</form>
@app.route('/',methods=['GET','POST'])
def index():
    form = Login()
    if form.validate_on_submit():  # 表单提交有效性验证
        name = form.username.data  # 两种获取方式
        pswd = request.form['password']
        return redirect(url_for("success"))
    else:
        if request.method=='POST':
            flash(u'信息有误,请重新输入!')
        print form.validate_on_submit()

    return render_template('index.html',form=form)
2.原生
from flask import Flask
app = Flask(__name__)

@app.route('/login', methods=['GET', 'POST']) # 默认为GET请求(渲染页面),需要添加POST(提交表单)
def  login():   
    if request.method == 'POST':
        # 第二次请求使用POST
        username = requst.forms['username']   # 表单中无action=''提交路径,默认返回当前页面
    # 第一次访问,渲染表单页面
    return render_template('login.html', method=request.method)

@app.route('/login_handle', methods=['POST']) # 一般提交至第二个视图处理,默认为GET请求,需要添加POST
def login_handle():
    username = request.forms['username']  # 获取表单数据
    return ...

if __name__ == '__main__':
    app.run()

15.SQLALchemy

Flask中关系型扩展,用来操作数据库

1.配置:

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://user_name:[email protected]:3306/database_name'

2.常用字段类型:

字段类型

​ 字段约束类型:

  • 主键约束:唯一且非空
  • 唯一约束:可以为null,但非null不可重复
  • 非空约束:not null
  • 外键约束:区关联主键,或者null

3.常用列选项:

列选项

4.常用关系选项:

关系选项

一对多
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'))

backref 为类User申明新属性的方法

lazy 决定了什么时候SQLALchemy从数据库中加载数据,如果设置为子查询方式subquer ,则会在加载完User对象后,就立即加载与其关联的对象,这样会让总查询数量减少,但如果返回的条目数量很多,就会比较慢,另外,也可以设置为动态方式dynamic ,这样关联对象会在被使用的时候再进行加载,并且在返回前进行过滤,如果返回的对象数很多,或者未来会变得很多,那最好采用这种方式

多对多
registrations = db.Table('registrations',  
    db.Column('student_id', db.Integer, db.ForeignKey('students.id')),  
    db.Column('course_id', db.Integer, db.ForeignKey('courses.id'))  
)  
class Course(db.Model):
    ...
class Student(db.Model):
    ...
    classes = db.relationship('Course',secondary=registrations,  
                                backref='student',  
                                lazy='dynamic')"

registrations 为格外创建的关联表

5.创建表以及插入数据

db.create_all()
data1 = Student(name = '1')
db.session.add(data1)    # 或者 db.session.add_all([data1, data2])
db.session.commit()

6.查询

常用SQLAlchemy查询过滤器

图片4

常用查询执行器

图片5

逻辑与:and_()

逻辑或:or_()

逻辑非:not_()

7.删除查询对象

stu1 = Student.query.first()
db.session.delete(stu1)
db.session.commit()

8.更新数据

stu1 = Student.query.first()
stu1.name = 'new_name'
db.session.commit()

16.数据库迁移flask-migrate

准备:

migrate = Manager(app, db)
manager = Manager(app)
manager.add_command('db', MiagrateCommand) # 注册至flask-script,方便在命令行管理

操作:

python app.py db init # 初始化  # db 为add_command()中设置的名称
python app.py db migrate -m'版本名' # 创建迁移文件,版本参数可以省略
python app.py db upgrade # 迁移
python app.py db history  # 历史版本
python app.py db downgrade 版本号  # 回滚

传入shell对象字典,避免每次shell操作导入

def make_shell_context():
    return dict(app=app, db=db,...)
manager.add_command('shell', Shell(make_context=make_shell_context))

17.发送邮件flask-mail

1.配置:(服务器,端口,安全套接字层/传输安全层协议,邮箱名,密码等)

app.config['MAIL_SERVER'] = 'smtp.126.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME']=
app.config['MAIL_PASSWORD']=
app.config['MY_MAIL_SENDER'] =   #发送者
app.config['MY_MAIL_TO']=   # 接收者

2.注册:

mail= Mail(app)

3.设置消息:

msg = Message(subject, sender='', recipientes=['to_1'], ...)
msg.body=''   或者   msg.html=''

4.发送:

mail.send(msg)

18.flask-bootstrap

bootstrap = Bootstrap(app)

19.flask-Moment(未完成)

moment = Moment(app)
moment.include_moment()

20.Blueprint

将项目文件模块化

1.创建蓝图对象

login = Blueprint('login', __name__,static_folder='', template_folder='')
# 同名文件,系统默认使用项目下默认的templates下文件,可以使用相对路径避免此问题

2.注册路由,指定静态文件夹,模板文件夹

@login.route('/')
def login_index():
    return 'login_index'

@login.route('/handle)
def login_handle():
    return 'login_handle'

3.在应用对象上注册蓝图

app.register_blueprint(login, url_prefix='/login')

static_url_path :可以为当前蓝图静态文件目录指定一个别名

使用url_for查询视图函数:url_for('login.login_index')

发布了42 篇原创文章 · 获赞 28 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章