【Flask】学习笔记(一)入门
Flask 入门基础
Flask是一个轻量级的后台框架,用Flask作为Web框架的公司有Netfix,Reddit等,国内豆瓣,果壳等。使用flask的公司列表。Flask 有主要的两个依赖,一个是WSGI(web server gateway Interface)web服务器网关接口,工具集-Werkzeug。另一个是Jinjia2模板引擎
一、搭建环境
1.安装pip,pipenv
python3.4以上版本pip已经自动安装好了
# 检查pip是否已经安装
$: pip --version
# 安装某个包,例如安装flask
$: pip install <包的名称>
$: pip install flask
# 安装pipenv(全局)
$: pip install pipenv
# 检查pipenv是否安装
$: pipenv --version
2.创建虚拟环境
虚拟环境通常用virtulenv来创建,为了更方便的关联虚拟环境和依赖包
$: pipenv install
3.pycharm使用省略
二、Hello Flask!
1.创建工程demo/helloflask
$: mkdir demo/helloflask
$: cd demo/helloflask
$: mkdir hello.py
$: pip install flask
$: vim hello.py
# 代码清单
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "hello flask"
if __name__ = '__main__':
app.run()
# 运行
$: python hello.py
2.步骤解析
2.1 实例化Flask类
- 从flask包中导入Flask类,实例化Flask类,得到一个实例。
- name : Flask类构造方法第一参数为模块或包的名称。帮助Flask找到需要的资源
from flask import Flask
app = Flask(__name__)
2.2 注册路由
- 用户在浏览器中输入url访问资源
- Flask接收到请求,并且分析url
- Flask为这个url找到对于的处理函数
- 执行这个函数,给出响应,返回给浏览器
- 浏览器接收解析响应,将在页面中展示信息
# 这一系列都是由Flask完成,我们只需要在函数上面添加一个装饰器app.route(),并传入url规则作为参数。可以让函数与url建立一个连接,这个过程叫做注册路由,函数称为视图函数
@app.route('/')
def hello():
return "hello flask"
2.3 启动Web服务器
if __name__ = '__main__':
app.run()
在启动的时候可以添加参数,在run()中
- debug : 是否开启调试模式,开启后修改的代码会自动重启
- threaded: 是否开启多线程
- port: 启动指定服务器的端口号,默认端口号5000
- host: 默认是127.0.0.1,指定0.0.0.0 支持远程访问
三、路由
3.1 一个视图可以绑定多个路由
- 访问127.0.0.1/index 127.0.0.1/hello 得到的response是一样的
@app.route('/index')
@app.route('/hello')
def index():
return 'hello, Flask!'
3.2 动态url
- url规则中添加变量
@app.route('/hello/<name>')
def index(name):
return 'hello %s' % name
- 当规则中包含变量,但是没有传入这个变量值的话(就是直接访问/hello)会报错的,所以要设置一个默认值
@app.route('/hello' , defaults={'name':'param'})
@app.route('/hello/<name>')
def index(name):
return 'hello %s' % name
- url参数前还可以添加转换器,转化参数类型
@app.route('/hello/<int:name_id>')
def index(name):
return 'hello %d' % name_id
四、HTTP请求以及相应
- http请求方式有get,post,put,delete,Flask路由规则设置请求方法
@app.route('/hello',methods = ['GET','POST'])
def index():
return 'hello flask'
- 重定向,例如当我们访问错误的时候,重定向到其他页面(状态码为302)
from flask import Flask, redirect
@app.route('/index')
def index():
return redirect('http://www.example.com')
- 重定向到其他视图页面
from flask import Flask, redirect, url_for
@app.route('/index')
def index():
return redirect(url_for('login'))
@app.route('/')
def login():
return "登入成功"
- 错误相应
from flask import Flask, abort
@app.route('/404')
def not_found():
abort(404)
五、模板与静态文件
- static: 存放图片,静态资源文件
- templates: 存放html文件
- 模板功能是基于Jinjia2模板引擎实现的
helloflask/
- static/
- templates/
- app.py
5.1 模板语法
- for if 常用控制模板输出
{% if %}..{% else %}..{% endif %}
{% for i in message %}..{% endfor %}
- 变量表达式
{{ }}
- 插入模板
{% include "index.html" %}
- 导入函数
{% from 'bootstrap/form.html' import render_form %}
{{ render_form(form) }}
- 继承模板
{% extends 'base.html' %}
- 块的开始与结束,一共6个块head、title、styles、content、footer和scripts
{% block content %}{% endblock %}
5.2 渲染模板
- 视图中使用render_template()
- templates/
index.html
@app.route('/')
def index():
return render_template('index.html')
5.3 过滤器
- 变量可以通过 过滤器 修改。过滤器与变量用管道符号( | )分割,并且也 可以用圆括号传递可选参数。多个过滤器可以链式调用,前一个过滤器的输出会被作为 后一个过滤器的输入。
- 将name变量标题化
{{ name|title }}
- 或者当前变量的长度
{{ movies|length }}
过滤器名 | 说明 |
---|---|
upper | 字母大写 |
lower | 字母小写 |
capitalize | 首字母大写 |
truncate(6,True) | 当前字符长度超过6显示...,默认是第二个参数是false |
default() | 默认字符串名 |
trim | 去除前后空格 |
safe | 关闭自动转义 |
round | 四舍五入取整 |
abs | 绝对值 |
first | 取第一个元素 |
last | 取最后一个元素 |
sum | 求和 |
sort | 排序默认升序 |
join | 合并为字符串 |
六、消息闪现
- Flask 提供了有用的flash() 函数,闪现需要给用户的消息,比如登入成功后会提示个消息,登入失败后也会提示个消息,需要在模板中使用全局函数get_flash_messages() 获取消息并将其显示
- 通过flash()函数发送的消息会存储在session对象中,所以我们需要为程序设置密钥。可以通过app.secret_key属性或配置变量SECRET_KEY设置
- app.py
from flask import Flask, render_template, flash, redirect, url_for
app = Flask(__name__)
app.secret_key = 'secret'
@app.route('/flash/')
def flask():
flash("闪现")
return redirect(url_for('hello_world'))
- template/index.html
<div>
{% for message in get_flashed_messages() %}
<div class="alert">{{ message }}</div>
{% endfor %}
</div>
- flash() 方法第二个参数似乎消息类型,可选择的有”message”, “info”, “warning”, “error”。只需设置get_flashed_messages()方法的with_categories和category_filter
参考:https://flask.palletsprojects.com/en/1.1.x/patterns/flashing/
七、数据库集成
7.1 ORM 概念
- 对象映射关系
- 让模型与数据库产生映射关系
- 操作模型对象可以实现数据库操作
- 表 -> python 类 ; 字段 -> 类属性 ;记录 -> 类实例
7.2 安装
$:pip install flask-sqlalchemy
对app对象初始化
db = SQLAlchemy()
db.init_app(app)
7.3 定义一张表
db = SQLAlchemy()
class User(db.Model):
__tablename__ == 'user'
name = db.Column(db.String(100))
no = db.Column(db.Integer(20))
字段 | 说明 |
---|---|
String | 字符串 |
Integer | 整型 |
Text | 文本 |
Date | 日期对象 Datetime.date |
Time | 时间对象 Datetime.time |
DateTime | 时间日期 |
Interval | 时间间隔 |
Float | 浮点数 |
Boolean | 布尔值 |
7.4 常用SQLAlchemy 字段参数
参数名 | 说明 |
---|---|
primary_key | 如果为True 该字段为主键 |
unique | 如果为True 该字段不允许重复 |
index | 如果为True 该字段创建索引 |
nullable | 该字段可否为空 |
default | 字段设置默认值 |
7.5 自定义表明
__tablename__ = ''
7.6 创建数据库
db.create_all()
7.7 删除数据库
db.drop_all()
7.8 数据库操作
# 调用add()方法将新创建的对象添加到数据库会话中
db.session.add(user)
# 提交会话
db.session.commit()
7.9 数据库读取
<模型类>.query.<过滤方法>.<查询方法>
https://docs.sqlalchemy.org/en/13/orm/query.html
查询方法 | 说明 |
---|---|
all() | 查询包含所有的记录列表 |
first() | 查询第一条数据,如果没有返回None |
get(ident) | 传入主键值为参数,返回猪圈记录 |
count() | 返回查询的数量 |
first_or_404() | 查询第一条记录,未找到返回404错误 |
with_paernt() | 传入模型作为参数,返回和这个实例相关联的对象 |
paginate() | 返回Pagination对象,对记录进行分页操作 |
https://docs.sqlalchemy.org/en/13/orm/query.html
过滤方法 | 说明 |
---|---|
filter() | 使用指定的规则过滤,返回新产生的对象 |
filter_by() | 使用指定的规则过滤(以关键字为对象),返回新产生的对象 |
order_by | 排序 |
group_by() | 根据查询的记录进行分组 |
offset() | 偏移查询结果 |
7.10 ORM 一对多
- 当前Author 代表作者,Article代表文章
class Author(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(70), unique=True)
phone = db.Column(db.String(20))
class Article(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50), index=True)
body = db.Column(db.Text)
- 在Article表中建立一个外键,用来在Ariticle的表中存储Author的主键值,建立关系
class Article(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50), index=True)
body = db.Column(db.Text)
author_id = db.Column(db.Integer, db.ForeignKey('author.id'))
- 定义关系属性,但是一个作者有多个文章
class Author(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(70), unique=True)
phone = db.Column(db.String(20))
articles = db.relationship('Article')
参数书籍:Flask开发实战