Flask最基本示例

1. app

# coding:utf-8
from flask import Flask, current_app, redirect, url_for

# 创建Flask的应用程序
# __name__表示当前的模块名字
#            模块名:flask以这个模块所在的目录为总目录,默认这个目录中的static为静态目录,templates为模板目录
app = Flask(__name__)
# app = Flask(__name__,
#             static_url_path='/python',  # 访问静态资源的url前缀,默认值是static
#             static_folder='static',  # 静态文件目录,默认就是static
#             template_folder='templates',  # 模板文件的目录,默认是templates
#             )
# 配置参数的使用方式
# 1.使用配置文件
# app.config.from_pyfile("config.cfg")

# 2.使用对象配置参数
# class Config(object):
#     DEBUG = True
#     ITCAST = "python" # 自用参数
# app.config.from_object(Config)

# 3.直接操作config的字典对象
# app.config["DEBUG"] = True

# 以装饰器形式绑定路由
@app.route('/')
def hello_world():
    # 读取配置参数
    # 1.直接从全局对象app的config字典中取值
    # print (app.config.get('ITCAST',''))
    # 2.通过current_app获取参数
    # print (current_app.config.get("ITCAST"))
    return 'Hello World!'


@app.route("/login")
def login():
    # url = "/"
    # 使用url_for的函数,通过视图函数的名字找到视图对应的url函数
    url = url_for("hello_world")
    return redirect(url)


if __name__ == '__main__':
    # 通过url_map可以查看整个flask中的路由信息
    print (app.url_map)
    # 启动flask程序
    app.run(debug=True)
    # app.run(host="0.0.0.0", port=5000)

2. url

# coding:utf-8
from flask import Flask, current_app, redirect, url_for

# 创建Flask的应用程序
# __name__表示当前的模块名字
#           模块名,flask以这个模块所在的目录为总目录,默认这个目录中的static为静态目录,templates为模板目录
app = Flask(__name__)

# 以装饰器形式绑定路由
@app.route('/')
def hello_world():
    return 'Hello World!'

# 通过method限定访问方式
@app.route("/post_only", methods=["GET","POST"])
def post_only():
    return "post only page"

# 给同一个url添加不同视图函数,利用method区别
@app.route("/hello", methods=["POST"])
def hello():
    return "hello 1"

@app.route("/hello", methods=["GET"])
def hello2():
    return "hello 2"

# 给同一个函数添加多个url
@app.route("/hi1")
@app.route("/hi2")
def hi():
    return "hi page"

@app.route("/login")
def login():
    # url = "/"
    # 使用url_for的函数,通过视图函数的名字找到视图对应的url函数
    url = url_for("hello_world")
    return redirect(url)



if __name__ == '__main__':
    # 通过url_map可以查看整个flask中的路由信息
    print (app.url_map)
    # 启动flask程序
    app.run(debug=True)
    # app.run(host="0.0.0.0", port=5000)

3. request

# -- coding: utf-8 --
from flask import Flask, request


app = Flask(__name__)


# 接口
# 127.0.0.1:5000/index?city=shenzhen&country=china 查询字符串QueryString
@app.route("/index", methods=["GET", "POST"])
def index():
    # request中包含了前端发送过来的所有请求数据
    # form和data是用来提取请求体中的参数
    # 通过request.form可以直接提取请求体中的表单格式的数据,是一个类字典的对象
    # 通过get方法只能拿到多个同名参数的第一个
    age = request.form.get("age", "23")
    name = request.form.get("name", "zhangsan")
    # args是用来提取url中的参数(查询字符串)
    city = request.args.get("city")
    # 通过getlist方法能拿到多个同名参数
    name_list = request.form.getlist("name")
    print (request.data)
    return "hello name=%s, age=%s, city=%s, name=%s" % (name, age, city, name_list)

# 表单格式数据
# city=value&age=value&gender=value
# file类型,必须给form标签添加 enctype="multipart/form-data"


if __name__ == "__main__":
    app.run(debug=True)

4. response

# -- coding: utf-8 --

from flask import Flask, request, abort, Response, make_response

app = Flask(__name__)


@app.route("/index", methods=["GET"])
def index():
    # 1.使用元祖,返回自定义的响应信息
    #         响应体      状态码             响应头
    # return "index page", 400, [("Itcast", "python",), ("City", "shenzhen")]
    # return "index page", "666 itcast status", {"Itcast": "python", "City": "shenzhen"}
    # return "index page", "666 itcast status"

    # 2.使用make_response来构造响应信息
    resp = make_response("index page 2")
    resp.status = "999 itcast" # 设置状态码
    resp.headers['city'] = "sz" # 设置响应头
    return resp


if __name__ == "__main__":
    app.run(debug=True)


4. upload_file

# -- coding: utf-8 --

from flask import Flask, request

app = Flask(__name__)


@app.route("/upload", methods=["POST"])
def upload():
    """接收前端传送过来的文件"""
    file_obj = request.files.get("pic")
    if file_obj is None:
        # 表示没有发送文件
        return "未上传文件"
    # 将文件保存到本地
    # 1.创建一个文件
    # with open("./demo.jpg","wb") as f:
    #     # 2.向文件内部写内容
    #     data = file_obj.read()
    #     f.write(data)

    # 直接使用上传的文件对象保存
    file_obj.save("./demo1.jpg")
    return "上传成功"


if __name__ == "__main__":
    app.run(debug=True)

5. cookie

# -- coding: utf-8 --
import json

from flask import Flask, make_response, request

app = Flask(__name__)


@app.route("/set_cookie")
def set_cookie():
    resp = make_response("success")
    # 设置cookie,默认有效期是临时cookie,浏览器关闭就失效
    resp.set_cookie("Itcast", "Python")
    resp.set_cookie("Itcast1", "Python1")
    # max_age设置有效期,单位:秒
    resp.set_cookie("Itcast2", "Python2", max_age=3600)
    return resp

@app.route("/get_cookie")
def get_cookie():
    c = request.cookies.get("Itcast2")
    return c

@app.route("/delete_cookie")
def delete_cookie():
    resp = make_response("del success")
    resp.delete_cookie("Itcast2")
    return resp


if __name__ == "__main__":
    app.run(debug=True)

6. session

# -- coding: utf-8 --
import json

from flask import Flask, session

# session_dict = {
#     "1":{
#
#     },
#     "2":{
#
#     }
# }

app = Flask(__name__)
# flask的session需要用到的秘钥字符串
app.config["SECRET_KEY"] = "SFJKDFSSDKJEGF"

# flask默认把session保存到了cookie中

@app.route("/login")
def login():
    # global session_dict
    # session_dict["1"][] =
    # 设置session数据
    session["name"] = "python"
    session["mobile"] = "18697118727"
    return "login success"


@app.route("/index")
def index():
    # 获取session
    name = session.get("name")
    return "hello %s" % name


if __name__ == "__main__":
    app.run(debug=True)

7. templates

# -- coding: utf-8 --
import json

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/index")
def delete_cookie():
    data = {
        "name": "python",
        "age": 18,
        "my_dict": {"city": "sz"},
        "my_list": [1, 2, 3, 4, 5],
        "my_int": 0
    }
    return render_template("index.html", **data)


if __name__ == "__main__":
    app.run(debug=True)

8. jsonify

# -- coding: utf-8 --
import json

from flask import Flask, jsonify

app = Flask(__name__)


@app.route("/index", methods=["GET"])
def index():
    # json就是字符串
    data = {
        "name": "python",
        "age": 18
    }
    # json_str = json.dumps(data)
    # return json_str, 200, {"Content-Type": "application/json"}
    # jsonify帮助转为json数据,并设置响应头 Content-Type为 application/json
    # return jsonify(data)
    return jsonify(city="sz", country="china")


if __name__ == "__main__":
    app.run(debug=True)

9. abort

# -- coding: utf-8 --

from flask import Flask, request, abort, Response

app = Flask(__name__)


@app.route("/login", methods=["GET"])
def login():
    # uname = request.form.get("uname")
    # upwd = request.form.get("upwd")
    uname = ""
    upwd = ""
    if uname != "zhangsan" and upwd != "admin":
        # 使用abort函数可以立即终止视图函数的执行
        # 并可以返回给前端特定的信息
        # 1.传递状态码信息,必须是标准的http状态码
        abort(404)
        # 2.传递响应体信息
        # resp = Response("login failed")
        # abort(resp)

    return "login success"


# 定义错误处理方法
@app.errorhandler(404)
def handle_404_error(err):
    """自定义的处理错误方法"""
    # 这个函数的返回值会是前端用户看到的最终结果
    return u"出现了404错误,错误信息:%s" % err


if __name__ == "__main__":
    app.run(debug=True)


10. converter

# -*- coding:utf-8 -*-

from flask import Flask, current_app, redirect, url_for
from werkzeug.routing import BaseConverter

# 创建Flask的应用程序
# __name__表示当前的模块名字
#           模块名,flask以这个模块所在的目录为总目录,默认这个目录中的static为静态目录,templates为模板目录
app = Flask(__name__)

# 转换器
# 127.0.0.1:5000/goods/123
# @app.route("/goods/")
@app.route("/goods/") # 不加转换器类型,默认是普通字符串规则(除了/的字符)
def goods(goods_id):
    """定义的视图函数"""
    return "goods detail page %s" % goods_id

# 1.定义自己的转换器
class MobileConverter(BaseConverter):
    def __init__(self, url_map):
        super(MobileConverter,self).__init__(url_map)
        self.regex = r"1[34578]\d{9}"

# 万能正则表达式
class RegexConverter(BaseConverter):
    """自定义转换器类"""
    def __init__(self, url_map, regex):
        # 调用父类的初始化方法
        super(RegexConverter,self).__init__(url_map)
        # 将正则表达式的参数保存到对象属性中,flask会使用这个属性来进行路由的正则匹配
        self.regex = regex

    def to_python(self, value):
        print ("to_pathon方法被调用")
        # return "abc"
        # value是在路径进行正则匹配的时候提取的信息
        return value

    def to_url(self, value):
        """使用url_for的方法的时候被调用"""
        return value


# 2.将自定义的转换器添加到flask的应用中
app.url_map.converters["re"] = RegexConverter
app.url_map.converters["mobile"] = MobileConverter

# 127.0.0.1:5000/send/12334566743
# @app.route("/send/")
@app.route("/send/")
def send_sms(mobile_num):
    return "send sms to %s" % mobile_num

@app.route("/index")
def index():
    # /send/18912345678
    url = url_for("send_sms",mobile_num="18912345678")
    return redirect(url)

if __name__ == '__main__':
    # 通过url_map可以查看整个flask中的路由信息
    print (app.url_map)
    # 启动flask程序
    app.run(debug=True)
    # app.run(host="0.0.0.0", port=5000)

11. SQLAlchemy

# -- coding: utf-8 --
from flask import Flask, render_template, request, redirect, url_for, jsonify
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
import pymysql
from flask_sqlalchemy import SQLAlchemy
pymysql.install_as_MySQLdb()

app = Flask(__name__)


class Config(object):
    # sqlalchemy的配置参数
    SQLALCHEMY_DATABASE_URI = "mysql://root:admin123@localhost:3306/author_book"
    # 设置sqlalchemy自动跟踪数据库
    SQLALCHEMY_TRACK_MODIFICATIONS = True

    SECRET_KEY = "DFDSGFGdsgfsgsg"

# 读取配置文件
app.config.from_object(Config)

# 创建sqlalchemy的数据库链接对象
db = SQLAlchemy(app)

# 创建flask脚本管理工具
manager = Manager(app)

# 创建数据库迁移工具对象
Migrate(app,db)

# 向manager对象中添加数据库操作命令
manager.add_command('db', MigrateCommand)


# 定义数据库的模型
class Author(db.Model):
    """作者"""
    __tablename__ = "tbl_authors"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32), unique=True)
    email = db.Column(db.String(32), unique=True)
    books = db.relationship('Book', backref="author")

    def __repr__(self):
        return '' % self.name


class Book(db.Model):
    """书籍"""
    __tablename__ = "tbl_books"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64),unique=True)
    author_id = db.Column(db.Integer, db.ForeignKey('tbl_authors.id'))

    def __repr__(self):
        return '' % self.name


# 创建表单模型类
class AuthorBookForm(FlaskForm):
    """作者数据表单模型类"""
    author_name = StringField(label=u"作者", validators=[DataRequired(u"作者必填")])
    book_name = StringField(label=u"书籍", validators=[DataRequired(u"书籍必填")])
    submit = SubmitField(label=u"保存")


@app.route("/", methods=['POST', 'GET'])
def index():
    # 创建表单对象
    form = AuthorBookForm()
    # 查询数据库
    if form.validate_on_submit():
        # 验证表单成功
        author_name = form.author_name.data
        book_name = form.book_name.data
        # 保存数据库
        author = Author.query.filter_by(name=author_name).first()
        if not author:
            author = Author(name=author_name)
            db.session.add(author)
            db.session.commit()
        book = Book.query.filter_by(name=book_name).first()
        if not book:
            book = Book(name=book_name, author_id=author.id)
            # book = Book(name=book_name, author_id=author)
            db.session.add(book)
            db.session.commit()

    authors = Author.query.all()
    return render_template("author_book.html", authors=authors, form=form)


# /delete_book?book_id=xxx
@app.route("/delete_book", methods=['POST'])
def delete_book():
    """删除数据"""
    # 提取参数(如果前端发生的请求体数据是json格式,get_json会解析成字典)
    # get_json要求前端传送的数据的Content-Type: application/json
    req_dict = request.get_json()
    book_id = req_dict.get("book_id")

    # 删除数据
    book = Book.query.get(book_id)
    db.session.delete(book)
    db.session.commit()

    return jsonify(code=0, message='OK')


if __name__ == "__main__":
    # 通过manager.run启动
    manager.run()
    # app.run(debug=True)
    # db.drop_all()
    # db.create_all()
    #
    # au_xi = Author(name=u"我吃西红柿", email="[email protected]")
    # au_qian = Author(name=u"萧潜", email="[email protected]")
    # au_san = Author(name=u"唐家三少", email="[email protected]")
    # db.session.add_all([au_xi, au_qian, au_san])
    # db.session.commit()
    #
    # bk_xi = Book(name=u"吞噬星空", author_id=au_xi.id)
    # bk_xi2 = Book(name=u"寸芒", author_id=au_qian.id)
    # bk_qian = Book(name=u"飘渺之旅", author_id=au_qian.id)
    # bk_san = Book(name=u"冰火魔厨", author_id=au_san.id)
    # db.session.add_all([bk_xi, bk_xi2, bk_qian, bk_san])
    # db.session.commit()

# 1、生成迁移文件
python 模块名.py db init

# 2、检查更新迁移文件,-m参数信息可省略不写
python 模块名.py db migrate -m "备注信息"

# 3、更新到数据库
python 模块名.py db upgrade

# 查询历史操作
python 模块名.py db history
# 回退操作
python 模块名.py db downgrade 要退回版本状态码

12. 模块测试

登录

# -- coding: utf-8 --

from flask import Flask, request, jsonify

app = Flask(__name__)


@app.route("/login", methods=["POST"])
def login():
    # 接收参数
    uname = request.form.get("uname")
    upwd = request.form.get("upwd")

    # 判断参数
    if not all([uname, upwd]):
        resp = {
            "code": 1,
            "message": "invalid params"
        }
        return jsonify(resp)
    if uname == "admin" and upwd == "python":
        resp = {
            "code": 0,
            "message": "login success"
        }
        return jsonify(resp)
    else:
        resp = {
            "code": 2,
            "message": "wrong uname or upwd"
        }
        return jsonify(resp)


if __name__ == "__main__":
    app.run(debug=True)

测试

# -- coding: utf-8 --

import unittest
from login import app
import json


class LoginTest(unittest.TestCase):
    """构造单元测试案例"""
    """构造单元测试案例"""
    def setUp(self):
        """在测试之前,先被执行"""
        # 创建进行web请求的客户端,使用flask提供的
		# 设置flask工作在测试模式下(以下两种方式2选1)
		# app.config['TESTING'] = True
		app.testing = True
        self.client = app.test_client()

    def test_empty_user_name_password(self):
        """测试用户名密码不完整的情况"""
        # 测试用户名和密码都不传
        # 利用client客户端模拟发送请求
        ret = self.client.post('/login', data={})
        # ret是视图返回的响应对象,data属性是响应体数据
        resp = ret.data
        # 因为login视图返回的是json字符串
        resp = json.loads(resp)
        # 拿到返回值开始断言测试
        self.assertIn("code", resp)
        self.assertEquals(resp['code'], 1)

        # 测试只传密码
        # 利用client客户端模拟发送请求
        ret = self.client.post('/login', data={"upwd": "python"})
        # ret是视图返回的响应对象,data属性是响应体数据
        resp = ret.data
        # 因为login视图返回的是json字符串
        resp = json.loads(resp)
        # 拿到返回值开始断言测试
        self.assertIn("code", resp)
        self.assertEquals(resp['code'], 1)

        # 测试只传用户名
        # 利用client客户端模拟发送请求
        ret = self.client.post('/login', data={"uname": "admin"})
        # ret是视图返回的响应对象,data属性是响应体数据
        resp = ret.data
        # 因为login视图返回的是json字符串
        resp = json.loads(resp)
        # 拿到返回值开始断言测试
        self.assertIn("code", resp)
        self.assertEquals(resp['code'], 1)

    def test_wrong_user_name_password(self):
        """测试用户名或密码错误"""
        # 测试用户名和密码都为错
        ret = self.client.post("/login",data={"uname": "iydsff", "upwd": "iughf"})
        # ret是视图返回的响应对象,data属性是响应体数据
        resp = ret.data
        # 因为login视图返回的是json字符串
        resp = json.loads(resp)
        # 拿到返回值开始断言测试
        self.assertIn("code", resp)
        self.assertEquals(resp['code'], 2)

        # 测试用户名错,密码对
        ret = self.client.post("/login", data={"uname": "iydsff", "upwd": "python"})
        # ret是视图返回的响应对象,data属性是响应体数据
        resp = ret.data
        # 因为login视图返回的是json字符串
        resp = json.loads(resp)
        # 拿到返回值开始断言测试
        self.assertIn("code", resp)
        self.assertEquals(resp['code'], 2)

        # 测试密码错,用户名对
        ret = self.client.post("/login", data={"uname": "admin", "upwd": "sfdf"})
        # ret是视图返回的响应对象,data属性是响应体数据
        resp = ret.data
        # 因为login视图返回的是json字符串
        resp = json.loads(resp)
        # 拿到返回值开始断言测试
        self.assertIn("code", resp)
        self.assertEquals(resp['code'], 2)

    def test_wright_user_name_password(self):
        """"测试用户名或密码错误"""
        # 测试用户名和密码都正确
        ret = self.client.post("/login", data={"uname": "admin", "upwd": "python"})
        # ret是视图返回的响应对象,data属性是响应体数据
        resp = ret.data
        # 因为login视图返回的是json字符串
        resp = json.loads(resp)
        # 拿到返回值开始断言测试
        self.assertIn("code", resp)
        self.assertEquals(resp['code'], 0)


if __name__ == "__main__":
    unittest.main()

你可能感兴趣的:(flask,Flask基本方法示例说明)