Flask总结

2019-06-16 22:57:37阅读 198评论 0

1.配置

1)静态文件配置

在app.views文件里,进行如下修改
blue=Blueprint('blog',name,static_folder='……')
#这里应放置static文件夹的绝对路径,如果不设置该属性,默认找当前文件同级的static文件夹

2)模板文件配置

在app.views.py文件里,进行如下修改
blue=Blueprint('blog',name,template_folder='……')
#这里应放置templates文件夹的绝对路径,如果不设置该属性,默认找当前文件同级的templates文件夹
3)数据库配置
在config.py 文件里,进行如下配置

    class DevelopEviroment(config):  
        DEBUG=True  
        TESTING=True  
        DATABASE={  
            'ENGINE':'mysql',  
            'DRIVER':'pymysql',  
            'USERNAME':'root',  
            'PASSWORD':'',  
            'HOST':'127.0.0.1',  
            'PORT':'3306',  
            'NAME':'test'  
        }#在这里进行配置  
        SQLALCHEMY_DATABASE_URI=get_db_url(DATABASE)

2.入口命令

1)运行服务

python manage.py runserver -h127.0.0.1 -p5000  

2)创建shell终端

python manage.py shell  

3)数据迁移

(1)初始化migrations

pythom manage.py db init  

(2)创建迁移版本(相当于django里的makemigrations)

python manage.py db migrate  

(3)进行迁移

python manage.py db upgrade  

(4)回退

python manage.py db downgrade

3.模型

1)字段

Integer数字
Float浮点数
String()文字,括号里设置字段长度
DateTime日期时间

2)字段约束属性

primary_key是否是主键
unique是否唯一
index是否设置索引
nullable是否允许为空
default默认值

3)字段关系

(1)一对多关系
(2)多对多关系

4)基本操作

详见Sqlalchemy使用

4.模板

1)模板继承

与django一致
{{super()}}保留父级block里的内容

2)包含

    <!DOCTYPE html>  
    <html lang="en">  
    <head>  
        <meta charset="UTF-8">  
        <title>Title</title>  
    </head>  
    <body>  
    <!-- 特殊的自定义 函数 -->  
    <h1>{{ request.url }}</h1>  
    <h2>{{ g.title }}</h2>  
    index  
    <br>  
    <!-- include 调用html文件 -->  
    {% include 'd2_include.html' %}  
    <hr>  
    <!-- 已经内置的特殊变量 -->  
    {{ url_for('detail') }}<br>  
    <a href="{{ url_for('detail') }}">详细页面</a>  
    </body>  
    </html>

3)静态文件

方法一

<link rel="stylesheet" href="/static/css/bootstrap.css">  

方法二

<link rel="stylesheet"
href="{{url_for('static',filename='css/bootstrap.css')}}">  

4)变量

{{name]}

5)宏定义

在模板中定义函数,在模板中调用后就渲染函数内部html

    {%macro hello()%}  
    <h1>hello,everyone<h1>  
    {%endmacro%}  
    调用  
    {{hello()}}  
    使用场景  
    一般和导入函数混用,将高频html代码封装到macro函数组成的html中,然后从中调取函数使用  
    {%from 'abc.html' import sayhi%}  
    {{sayhi()}}

6)过滤器

{{ 'hello' | safe }}标记安全
{{ 'hello' | striptags }}删除标签

7)自定义过滤器

    # step1 定义过滤器  
    def do_listreverse(li):  
        temp_li = list(li)  
        temp_li.reverse()  
        return temp_li  
    # step2 向app添加自定义过滤器  
    app.add_template_filter(do_listreverse, 'listreverse')

8)流程控制

(1)条件

    {% if comments | length > 0 %}  
        There are {{ comments | length }} comments  
    {% else %}  
        There are no comments  
    {% endif %}

(2)循环

    {% for post in posts %}  
        <div>  
            <h1>{{ post.title }}</h1>  
            <p>{{ post.text | safe }}</p>  
        </div>  
    {% endfor %}

5.视图

1)CBV

    from flask import views  
    class index(views.MethodView):  
        methods=['GET']  
        decorators=[]  
        def get(self):#定义get方法  
            return 'are you ok'  
    blue.add_url_rule('/index',view_func=index.as_view(name='index'))#将路由添加到app中,其中name='index'相当于endpoint='index'

2)request

(1)args和values
args返回url中的键值对(GET方式提交的数据),values返回url+请求体中的键值对
(2)form
返回请求体中的键值对(POST方式提交的数据)

获取js提交的数组

    @app.route("/server",methods=["POST"])  
    def server(){  
        list = request.form.getlist("list[]")

      print(list)  
    }

结果

    ['1', '2', '3', '4']

(3)headers
请求头
(4)url、path、script_root、base_url、url_root

    @blue.route('/login',methods=['GET','POST'],endpoint='login')  
    def login():  
        if request.method=='GET':  
            print('___start____')  
            print(request.url)  
            print(request.path)  
            print(request.script_root)  
            print(request.base_url)  
            print(request.url_root)  
            print('___end____')  
            return render_template('login.html')

结果

    ___start____  
    http://127.0.0.1:5000/admin/login?abc=123  
    /admin/login  

    http://127.0.0.1:5000/admin/login  
    http://127.0.0.1:5000/  
    ___end____  
    127.0.0.1 - - [16/Jun/2019 17:05:34] "GET /admin/login?abc=123 HTTP/1.1" 200 -

(5)files

    from flask import request,json  
    from app.config import BASE_DIR#自定制配置  
    import os,uuid  
    @blue.route('/upload',methods=['GET','POST'])  
    def upload():  
        if request.method=='GET':  
            return render_template('upload.html')  
        elif request.method=='POST':  
            r_data={'code':1}  
            f=request.files['file1']  
            ext=os.path.splitext(f.filename)[1]#获取文件后缀  
            new_filename=uuid.uuid4().hex+ext#用uuid重新命名  
            f.save(os.path.join(BASE_DIR,'uploadfiles',new_filename))#保存文件  
            return json.jsonify(r_data)

3)response

(1)render_template()
基于response对象,第一个参数传模板名,后面的参数传渲染到模板的变量
(2)jsonify()
基于response对象,返回json,传入参数为字典
4)redirect
跳转到新页面,使用蓝图并配置url_prefix需要注意

6.路由

1)写法和原理

    @blue.route('/sayhi',methods=['GET','POST'],endpoint='sayhi')#在视图函数上添加装饰器,并将url、methods传入,endpoint为该url命名,如果未设置默认为视图函数名      
    from flask import url_for  
    def sayhi():  
        url_index = url_for('app01.index')#反向解析参数结构:蓝图名.路由名  
        print(url_index)  
        return 'hello,everyone'

本质上是在app上新增url,即app执行add_url_rule方法,和以下写法类似

    from flask import url_for  
    def sayhi():  
        url_index = url_for('app01.index')  
        print(url_index)  
        return 'hello,everyone'  
    blue.add_url_rule('/sayhi','sayhi',sayhi,methods=['GET'])

2)登陆验证装饰器问题

    import functools  
    def login_v(func):#定义登陆装饰器  
        @functools.wraps(func)  
        def inner(*args,**kwargs):  
            if not session.get('username'):#如果未设置session将会跳转到登陆页面  
                return redirect(url_for('app01.login'))  
            return func(*args,**kwargs)  
        return inner  

    @blue.route('/test')  
    @login_v  
    def test():  
        return 'this is test'

7.蓝图

    from flask import Blueprint  
    blue=Blueprint('app01',__name__)#将views文件定义成蓝图  
    def init_first_blue(app):  
        app.register_blueprint(blueprint=blue,url_prefix='/admin')#注册蓝图,url_prefix表示访问此蓝图的url需要加前缀/admin  
    @blue.route('/')#所有路由必须用蓝图  
    def index():  
        return 'hello'

8.csrf_token

1)在ext.py中配置插件

    from flask_wtf.csrf import CSRFProtect  
    crsf=CSRFProtect()  
    def init_ext(app):  
            crsf.init_app(app)

2)说明

所有模板中,涉及表单提交的,在提交的时候请求头上需要设置{'X-CSRFtoken':'{{csrf_token()}}'},否则会导致提交失败

9.session

用户访问时,生成一个唯一的随机字符串,客户端、服务的各一份,服务端以此随机字符串,识别用户身份,并以此生成键值对加密后保存用户登陆等信息。
flask自带session(from flask import
session),在服务端没有存储session数据,而是随机字符串和身份信息加密后保存到客户端,存在安全隐患。
所以一般用flask_session插件,使用前需要安装(pip install
flask_session)可以将session数据保存在redis,memecache,filesysterm,mongodb,sqlalchemy中,以下是配置及使用方法
配置信息:

    app.config['SESSION_TYPE'] = 'redis' # session类型为redis  
    app.config['SESSION_PERMANENT'] = False # 如果设置为True,则关闭浏览器session就失效。  
    app.config['PERMANENT_SESSION_LIFETIME']=timedelta(days=31)  
    app.config['SESSION_USE_SIGNER'] = False # 是否对发送到浏览器上session的cookie值进行加密  
    app.config['SESSION_KEY_PREFIX'] = 'session:' # 保存到session中的值的前缀  
    app.config['SESSION_REDIS'] = redis.Redis(host='127.0.0.1', port='6379', password='123123') # 用于连接redis的配置

初始化到app:
在ext.py中

    from flask_session import Session  
    session=Session()  
    def init_ext(app):  
            session.init_app(app)

还没有评论,来说两句吧