Python Flask 笔记

1、虚拟环境
1)安装虚拟环境

    sudo pip install virtualenv 

    sudo pip install virtualenvwrapper 

2)查看 虚拟环境版本

    virtualenv --version

3)配置环境变量

    mkdir $HOME/.virtualenvs

    vim ~/.bashrc

    添加    export WORKON_HOME=$HOME/.virtualenvs

                source /usr/local/bin/virtualenvwrapper.sh

    source ~/.bashrc

4)创建虚拟环境

    mkvirtualenv Flask_py

5)进入虚拟环境

    workon Flask_py

6)退出虚拟环境

    deactivate  Flask_py

7)查看当前虚拟环境工具包

    pip freeze > requirements.txt

8)根据工具包版本安装工具包

    pip install -r requirements.txt

2、demo
from flask import Flask

app = Flask(__name__)

@app.route('/',    methods=['GET', 'POST'])    //装饰器定义路径和调用方法

def index():

    return 'index page'

if __name__ == '__main__':

    app.run()

3、print(name) // demo.py
入口文件打印 main

非入口文件打印     demo  

4、静态文件设置
app = Flask(name,

                    static_url_path = '/static',    //访问静态资源前缀

                    static_floder = 'static',        //静态资源目录

                    template_floder = 'templates')    //模版目录

5、设置配置信息、current_app(app的同名词)
from flask import Flask, current_app

class Config():

    debug = True

    lang = python

app.config.from_object(Config)

@app.route('/')

def index():

    print(app.config.get('debug'))     //True

    print(current_app.config.get('debug'))     //True

    return 'index'

6、同一个路由对应多个试视图函数,执行第一个
7、多个路径对应同一个视图函数,通过添加多个装饰器的方式添加
8、redirect、url_for
from flask

@app.route('/')

def index():

    return 'index.html'

@app.route('/login')

def login():

    if login:

        redirect(url_for('index'))

9、转换器
@app.route(’/send/int:mobile’)

def senfMobile(mobile):

    return 'mobile is %d' % mobile 

10、自定义转换器、to_python、to_path函数(过滤)
from werkzeug.routing import BaseConverter

//定义转换器类

class RegexConverter(BaseConverter)        

    def __init__(self, url_map, regex):

        super(RegexConverter, self).__init__(url_map)       

        self.regex = regex

    def to_python(self, value):

        return value

    def to_url(self, url):

        return url

//添加转换器

app.url_map.converters['re'] = RegexConverter        

//应用        根据正则表达式匹配对应的参数

app.route('/send/<re(r'1[345678]\d{9}'):mobile>')      

def send_mobile(mobile):

    return 'mobile is %d' % mobile

11、request data、form、args、values、files、json
前端from表单

    application/x-www-form-urlencoded          与后端交互默认值    

    multipart/form-data                                    一般用于上传包含图片文件的数据    

    text/plain                                                    发送纯文本数据

当请求没有设置Content-Type:application/json时,Body里面的数据都会放到request.data

当请求有设置Content-Type:application/json时,Body里面的数据都会放到request.json           

获取queryString参数用request.args

request.form            接收表单数据       request.form.getlist()       获取多个重名参数列表

request.value           替代form和args 

request.files             获取form中的文件

12、上传文件
f = request.file.get(‘name’)

f.save('url')

//save函数过程

file_obj = request.file.get('name')

f = open('./url.jpg','wb')

data = dile_obj.read()

f.write(data)

f.close() 

13、abort函数、自定义异常处理函数
abort(404) 提前终止函数,并返回状态404

自定义异常处理函数

@app.errorhandler(404)

def handle_error_404(error):

    return error

14、返回自定义信息
from flask import Flask, jsonify

import json

app = Flask(__name__)

@app.route('/')

def index():

    data = {

        "name":"sgr","age":'"18"

    }

    json_str = json.dumps(data)

    return json_str , 200, {"Content-Type":"application/json"}        //返回页面信息    状态码    响应头信息

    return jsonify(json_str)        //等价于上一行

if __name__ == '__main__':

    app.run()

15、设置、读取、删除cookie信息
from flask import Flask, make_response

app = Flask(__name__)

@app.route('/set_cookie')

//设置cookie信息 其实是通过传递响应头信息的方式

def set_cookie():

    resp = make_response('set cookie')

    resp.set_cookie("name", "sgr", max_age = 3600)

    resp.headers["Set-Cookie"] =  "name=sgr"    

    return resp

@app.route('get_cookie')

def get_cookie():

    cookie_msg = request.cookies.get("name")

    return cookie_msg

//删除cookie函数    是修改过期时间的方式

def del_cookie():

    resp = make_response('del_cookie')

    resp.delete_cookie('name')

    return resp

if __name__ == '__main__':

    app.run()

16、session机制
from flask import Flask,session

app = Flask(__name__)

app.config['SECRET_KEY'] = 'skhsjjsgdjshsgssj'    //设置session信息必须设置secret_key

@app.route('/login')

def login():

    session['name'] = 'sgr'

    session['mobile'] = 'xxx'

    return 'session'

@app.route('/index')

def index():

    name = session.get("name")

    return name

if __name__ == '__main__':

    app.run()

session第一次登录的时候并没有session_id,登陆以后session_id返回给浏览器,之后每次交互,都会带着session信息

session信息是保存再服务器端的数据,cookie保存在前端,cookie信息不安全,但是flask是把session信息保存在了session中,也不安全,flask通过secret_key将保存的 session信息进行了混淆处理,当发现改变时失效

如果session信息保存再机器内存中,服务器集群负载均衡,分发任务,可能既不会发送给之前存储session信息的机器,此时不存在session信息,这种一般根据地区进行分发,可以得到解决

线上会使用专门的redis机器,进行存储信息,此时不论引导到哪个机器,都只有一个数据源

如果没有cookie保存session_id,可以通过登录重定向,通过url进行保存信息(部分国家认为cookie是私有信息,需要授权),部分网站会有sid属性,无法设置有效时长

17、钩子函数
    from flask import Flask

    app = Flask(__name__)

    @app.before_first_request()

    def before_first_request():

        print('第一次请求前')

    @app.before_request()

    def before_request():

        print('执行请求之前')

    @app.after_request(response)

    def after_request():

        print('执行请求之后')

        return response

    @app.teardown_request(response)    //调试模式不执行

    def teardown_request():

        return response

    if __name__ == '__main__':

        app.run()

18、应用上下文 current_app、g
一次请求内多个函数之间参数传递

19、flask-script (runserver 和 shell)
from flask import Flask

from flask_script import Manager

app = Flask(__name__)

manager = Manager(app = app)

@app.route('/')

def index():

    return 'index page'

if __name__ == '__main__':

    manager.run()

启动命令

python3 demo.py runserver 

启动参数

-r(reload 重启)-d(debug 调试模式)    -th(多线程)    -p(port 端口)    -h(host  域名)

20、模版与自定义过滤器
data = {

    name:'sgr',

    age:'18'

}

render_template('index.html',   **data )    //模板路径和数据数据  

render_template('index.html',    name='sgr',    age='18')    //模板路径和数据数据  

内置过滤器

safe             禁止转义

capitalize    首字母大写

lower           小写

upper          大写

title             每个单词首字母大写

trim             去除左右空格

reverse       字符串反转

striptage      去除html标签

format          格式化输出(  {{  "%s is %d" | format("name",18)   }} )

自定义过滤器

def fliter_step2( list ):

    return list[::2]

app.add_template_filter(filter_step2, list2)         //参数:(函数名称,作为过滤器的名称)

21、flask-wtf
模型类表单使用 demo.py

demo

22、宏
定义

{% macro input() %}

    <input type= "text"

            name = "username"

            value= ""

            size = "30">

{% endmacro %}

使用

{{ input() }}

外部导入

{% import "macro_input.html" as m_input %}

调用

{% m_input.input() %}

23、flash(闪现)
引入

from flask import Flask,flash

@app.route('/login', methods=['GET', 'POST'])

def login():

    error = None

    if request.method == 'POST':

        if request.form['username'] !=   app.config['USERNAME']:

            error = 'Invalid username'

        elif request.form['password'] != app.config['PASSWORD']:

            error = 'Invalid password'

        else:

            session['logged_in'] = True

            flash('You were logged in')

            return redirect(url_for('index'))

    return render_template('login.html', error=error) 

获取

{% for message in get_flashed_messages()            

    {{message}}

{% endfor %}

flash和它的名字一样,是闪现,意思就是我们的消息只会显示一次,当我们再次刷新也面的时候,它就不存在了,而正是这点,它经常被用来显示一些提示消息,比如登陆之后,显示欢迎信息等

24、sqlalchemy
pip install flask-sqlalchemy

pip install flask-mysqldb

from flask import Flask

from flask_sqlalchemy import SQLAlchemy

from sqlalchemy import func        

app = Flask(__name__)

class Config(): 

    SQLALCHEMY_DATABASE_URI = 'mysql://root:mysql@127.0.0.1:3306/test'

    #   mysql://用户名:密码@127.0.0.1:3306/数据库名

    SQLALCHEMY_TRACK_MODIFICATIONS = True

    #  True 让数据库里面的数据和模型数据库里面的数据保持一致

    SQLALCHEMY_ECHO = True

app.config.from_object(Config)

db = SQLAlchemy(app)

class User(db.Model):

    __tablename__ = "tbl_users"

    id = db.Column(db.Integer, primary_key = True)

    name = db.Column(db.String(64), unique = True)

    email = db.Column(db.String(128), unique = True)

    password = db.Column(db.String(128))

    role_id = db.Column(db.Integer, db.ForeignKey("tbl_roles.id"))  

class Role(db.Model):

    __tablename__ = "tbl_roles"

    id = db.Column(db.Integer, primary_key = True)

    name = db.Column(db.String(32), unique = True)   

    users = db.relationship("User", backref = "role")

    def __repr__(self):

        return "Role Object name=%s" % self.name

if __name__ == '__main__':

    db.create_all()    //创建所有数据库    

    role1 = Role(name = "admin")                           //创建用户

增加数据

    user1 = User(name="sgr",email="xxx.com",password="xxx",role_id=role1.id)

    db.session.add(role1)                                       //添加数据

    db.session.add_all(role1, role2, role3)             //批量添加数据

    db.session.commit()                                         //提交数据库

查询数据

    Role.query.all()                                                  //查询数据

    db.session.query(Role).all()                             //

    Role.query.first()                                               //查询一条数据

    Role.query.get('1')                                            //查询一条数据(主键)

    Role.query.filter_by(name = "wang", role_id = 1).all()              

    Role.query.filter(User.name == "wang", User.role_id == 1).all()        //  与上面等价

    Role.query.filter(or_(User.name == "wang", User.email.endswith("163.com"))).all()      //或查询

    Role.query.filter().offset().limit().order_by(User.id.desc()).all()    //链式顺序

    db.session.query(User.role_id, func.count(User.role_id)).group_by(User.role_id).all()

    select role_id, count(role_id) from User group by role_id

 修改数据

1)、 user = db.session.query(User).get(1)

          user.name = 'python'

          db.session.add(user)

          db.session.commit()

 2)、db.session.query(User).filter_by(name="zhou").update({"name":"python"})

          db.session.commit()

 删除数据

 user  = db.session.query(User).get(1)

  db.session.delete(user)

  db.session.commit()

  //案例

25、migrate扩展 
https://www.jianshu.com/writer#/notebooks/49587685/notes/85758743

26、flask-blueprint
main.py

from flask import Flask

from goods import app_goods

from user import register

app = Flask(__name__)

app.register_blueprint(app_goods, url_prefix="/goods")

app.route('/user')(register)

@app.route('/')

def index():

    return 'index' 

if __name__ == "__main__":

    app.run()

user.py 

def register():

    return 'register'

goods.py

from flask import Blueprint

app_goods = Blueprint("app_goods", __name__)

@app_goods.route('/get_goods')

def get_goods():

    return 'get_goods page'    

27、以目录的结构定义蓝图
文件目录

main.py

from flask import Flask

from flask_script import Manager

from cart import app_cart

app = Flask(__name__)

manager = Manager(app=app)

app.register_blueprint(app_cart, url_prefix="/cart")

if __name__ == '__main__':

    manager.run()

__init__.py

from flask import Blueprint

app_cart = Blueprint("app_cart", __name__)

from .views import get_cart

views.py

from . import app_cart

@app_cart.route("/get_cart")

def get_cart():

return 'get_cart'

28、断言
    assert isinstance(num, int)

29、单元测试
    login.py

    from flask import Flask, request, jsonify

    app = Flask(__name__)

    @app.route('/login', methods=['POST'])

    def login():

        username = request.form.get("username")

        password = request.form.get("password")

        if not all([username, password]):

            resp = {

                "code":0,

                "msg":"invalide params"

            } 

            return jsonify(resp)

        if uasename == "name" and password == "python":

            resp = {

                "code":1,

                "msg":"login success"

            }

            return jsonify(resp)

        else:

            resp = {

                "code":2,

                "msg":"username or password is not right"

            }

            return jsonify(resp)

    if __name__ == '__main__':

        app.run()       

    接口测试

    test.py 

    import unittest

    from login import app

    import json

    class LoginTest(unittest.TestCase):

        def setUp(self):                                            //相当于__init__函数

            self.client = app.test_client()

            app.testing = True                                   //打开测试模式,可以查看具体的错误信息

        def test_username_empty(self): 

            ret = self.client.post("/login", data = {})

            resp = ret.data

            resp = json.loads(resp)

            self.assertIn("code", resp)

                self.assertEqual(resp["code"],0)

if __name__ == '__main__':

    unittest.main()

数据库操作

database.py

import unittest

from author_book import db, app, Author

class DatabaseTest(unittest.TestCase):

    def setUp(self):

        self.testing = True

        self.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:password@127.0.0.1:3306/test"

        db.create_all()

    def test_add_author(self):

        author = Author(name="zhang", email="1057@qq.com", mobile="13678787878")

        db.session.add(author)

        db.session.commit()

        result = db.session.query(Author).filter_by(name="zhang").first()

        self.assertIsNotNone(result)

    def teardown(self):

        db.session.remove()

        db.drop_all()

30、部署(nginx + gunicorn + flask)
gunicorn
pip install gunicorn

gunicorn -h (帮助信息)

启动命令

gunicorn -w 4 -b 127.0.0.1:5000 -D --access-logfile ./logs/access_log main:app

         -w   开启子进程

         -b    当前服务器绑定到哪个ip、端口

         -D    守护进程对方式运x行

         --access-logfile  ./logs/    日志信息

         main:app                          main.py中的app对象

ps aux | grep gunicorn    查看gunicorn进程

kill -9 进程id号                杀死进程

nginx 
安装启动命令 mac

https://blog.csdn.net/weixin_39788856/article/details/94540125

 配置文件
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值