Flask基础知识

Posted shengjunqiye

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask基础知识相关的知识,希望对你有一定的参考价值。

简介:

Flask基于python开发并依赖于jinjia2和werkzeug WSGI服务一个微型框架.

Werkzeug本质是Socket服务端,用来接收http请求并对请求进行预处理,然后触发Flask框架,

开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂内容时,

需要借助jinjia2模板来实现对模板的处理,即:将模板和数据进行渲染,江选然后的字符串返回给用户.

我们用python直接写Web业务,剩下的TCP连接,HTTP原始请求和响应格式就需要一个统一的接口协议来实现,

这个接口就是WSGI(Web Server Gateway Interface),wsgiref就是python基于wsgi协议开发的服务模块.代码如下:

from wsgiref.simple_server import make_server

def mya(environ, start_response):
    print(environ)
    start_response(200 OK, [(Content-Type, text/html)])
    if environ.get(PATH_INFO) == /index:
        with open(index.html,rb) as f:
            data=f.read()

    elif environ.get(PATH_INFO) == /login:
        with open(login.html, rb) as f:
            data = f.read()
    else:
        data=b<h1>Hello, web!</h1>
    return [data]

if __name__ == __main__:
    myserver = make_server(‘‘, 8011, mya)
    print(监听8010)
    myserver.serve_forever()

wsgiref简单应用

我们平时写flask的代码其实就是在改写mya这个函数的内容

 

 

1.安装Flask:

pip install flask

2.Werkzeug

Werkzeug是WSGI的一个工具包,可以作为Web框架的底层库.(因为Werkzeug里面封装了好多web框架的东西,入Request,Response等)

代码:

from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
    return Response(Hello World!)

if __name__ == __main__:
    from werkzeug.serving import run_simple
    run_simple(localhost, 4000, hello)

 

3.flask简单使用

from flask import Flask
# 实例化产生一个Flask对象
app = Flask(__name__)
# 将 ‘/‘和视图函数hello_workd的对应关系添加到路由中,flask所有的路由都是在装饰其中添加的
@app.route(/) # 1. v=app.route(‘/‘) 2. v(hello_world)
def hello_world():
    return Hello World!

if __name__ == __main__:
    app.run() # 最终调用了run_simple()

 

例子:登录,显示用户信息

主文件(xxx.py):

from flask import Flask,render_template,request,redirect,session,url_for
app = Flask(__name__)
app.debug = True
app.secret_key = sdfsdfsdfsdf

USERS = {
    1:{name:张三,age:18,gender:,text:"道路千万条"},
    2:{name:李四,age:28,gender:,text:"安全第一条"},
    3:{name:王五,age:18,gender:,text:"行车不规范"},
}

@app.route(/detail/<int:nid>,methods=[GET])
def detail(nid):
    user = session.get(user_info)
    if not user:
        return redirect(/login)

    info = USERS.get(nid)
    return render_template(detail.html,info=info)


@app.route(/index,methods=[GET])
def index():
    user = session.get(user_info)
    if not user:
        # return redirect(‘/login‘)
        url = url_for(l1)
        return redirect(url)
    return render_template(index.html,user_dict=USERS)


@app.route(/login,methods=[GET,POST],endpoint=l1)
def login():
    if request.method == "GET":
        return render_template(login.html)
    else:
        # request.query_string
        user = request.form.get(user)
        pwd = request.form.get(pwd)
        if user == cxw and pwd == 123:
            session[user_info] = user
            return redirect(http://www.baidu.com)
        return render_template(login.html,error=用户名或密码错误)

if __name__ == __main__:
    app.run()

 

 

前端:

三种前端取值方式:

①dic.name

②dic[‘name‘]

③dic.get(‘name‘)

 

html文件:

detail.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>详细信息 {{info.name}}</h1>
    <div>
        {{info.text}}
    </div>
</body>
</html>

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>详细信息 {{info.name}}</h1>
    <div>
        {{info.text}}
    </div>
</body>
</html>

 

 

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>用户登录</h1>
    <form method="post">
        <input type="text" name="user">
        <input type="text" name="pwd">
        <input type="submit" value="登录">{{error}}
    </form>
</body>
</html>

 

4.flask的配置文件:

 {
        DEBUG:                                get_debug_flag(default=False),  是否开启Debug模式
        TESTING:                              False,                          是否开启测试模式
        PROPAGATE_EXCEPTIONS:                 None,                          
        PRESERVE_CONTEXT_ON_EXCEPTION:        None,
        SECRET_KEY:                           None,
        PERMANENT_SESSION_LIFETIME:           timedelta(days=31),
        USE_X_SENDFILE:                       False,
        LOGGER_NAME:                          None,
        LOGGER_HANDLER_POLICY:               always,
        SERVER_NAME:                          None,
        APPLICATION_ROOT:                     None,
        SESSION_COOKIE_NAME:                  session,
        SESSION_COOKIE_DOMAIN:                None,
        SESSION_COOKIE_PATH:                  None,
        SESSION_COOKIE_HTTPONLY:              True,
        SESSION_COOKIE_SECURE:                False,
        SESSION_REFRESH_EACH_REQUEST:         True,
        MAX_CONTENT_LENGTH:                   None,
        SEND_FILE_MAX_AGE_DEFAULT:            timedelta(hours=12),
        TRAP_BAD_REQUEST_ERRORS:              False,
        TRAP_HTTP_EXCEPTIONS:                 False,
        EXPLAIN_TEMPLATE_LOADING:             False,
        PREFERRED_URL_SCHEME:                 http,
        JSON_AS_ASCII:                        True,
        JSON_SORT_KEYS:                       True,
        JSONIFY_PRETTYPRINT_REGULAR:          True,
        JSONIFY_MIMETYPE:                     application/json,
        TEMPLATES_AUTO_RELOAD:                None,
    }

 

 

配置上述配置时,在主文件的函数中写:

法一:

   app.config[DEBUG] = True
   
   app.debug=True 也行
    
   PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...)

 

法二:

#通过py文件配置
app.config.from_pyfile("python文件名称")
如:
settings.py
DEBUG = True

app.config.from_pyfile("settings.py")
#通过环境变量配置
app.config.from_envvar("环境变量名称")
#app.config.from_pyfile(os.environ[‘YOURAPPLICATION_SETTINGS‘])
环境变量的值为python文件名称名称,内部调用from_pyfile方法

app.config.from_json("json文件名称")
JSON文件名称,必须是json格式,因为内部会执行json.loads

app.config.from_mapping({DEBUG: True})
字典格式

app.config.from_object("python类或类的路径")

app.config.from_object(pro_flask.settings.TestingConfig)

settings.py


class Config(object):
    DEBUG = False
    TESTING = False
    DATABASE_URI = sqlite://:memory:


class ProductionConfig(Config):
    DATABASE_URI = mysql://user@localhost/foo


class DevelopmentConfig(Config):
    DEBUG = True


class TestingConfig(Config):
    TESTING = True


PS: 从sys.path中已经存在路径开始写

PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录(Flask对象init方法的参数)

 

5.flask路由

标准语法:
    @app.route(/detail/<int:nid>,methods=[GET],endpoint=detail)

默认转换器

DEFAULT_CONVERTERS = {
    default:          UnicodeConverter,
    string:           UnicodeConverter,
    any:              AnyConverter,
    path:             PathConverter,
    int:              IntegerConverter,
    float:            FloatConverter,
    uuid:             UUIDConverter,
}

 

路由系统本质:

"""
1. decorator = app.route(‘/‘,methods=[‘GET‘,‘POST‘],endpoint=‘n1‘)
    def route(self, rule, **options):
        # app对象
        # rule= /
        # options = {methods=[‘GET‘,‘POST‘],endpoint=‘n1‘}
        def decorator(f):
            endpoint = options.pop(‘endpoint‘, None)
            self.add_url_rule(rule, endpoint, f, **options)
            return f
        return decorator
2. @decorator
    decorator(index)
"""
#同理
def login():
    return 登录
app.add_url_rule(/login, n2, login, methods=[GET,"POST"])
#与django路由类似
#django与flask路由:flask路由基于装饰器,本质是基于:add_url_rule
#add_url_rule 源码中,endpoint如果为空,endpoint = _endpoint_from_view_func(view_func),最终取view_func.__name__(函数名)

 

6.模板

渲染变量:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>用户列表</h1>
    <table>
        {% for k,v in user_dict.items() %}
        <tr>
            <td>{{k}}</td>
            <td>{{v.name}}</td>
            <td>{{v[name]}}</td>
            <td>{{v.get(name)}}</td>
            <td><a href="/detail/{{k}}">查看详细</a></td>
        </tr>
        {% endfor %}
    </table>
</body>
</html>


变量循环:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>用户列表</h1>
    <table>
        {% for k,v in user_dict.items() %}
        <tr>
            <td>{{k}}</td>
            <td>{{v.name}}</td>
            <td>{{v[name]}}</td>
            <td>{{v.get(name)}}</td>
            <td><a href="/detail/{{k}}">查看详细</a></td>
        </tr>
        {% endfor %}
    </table>
</body>
</html>


逻辑判断:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>用户列表</h1>
    <table>
        {% if name %}
          <h1>Hello {{ name }}!</h1>
        {% else %}
          <h1>Hello World!</h1>
        {% endif %}
    </table>
</body>
</html>

 

传参:直接在return后面的口号内直接加逗号,直接写参数即可

主文件:
from flask import Flask,render_template,Markup,jsonify,make_response
app = Flask(__name__)

def func1(arg):
    return Markup("<input type=‘text‘ value=‘%s‘ />" %(arg,))
    #Markup和django的make_safe一样
@app.route(/)
def index():
    return render_template(index.html,ff = func1)#参数func1就传过去了

if __name__ == __main__:
    app.run()

    
    
 html文件中:
    
 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    {{ff(六五)}}  #使用ff变量
    {{ff(六五)|safe}}

</body>
</html>

 

extends,include和django一样

7.请求响应:

   from flask import Flask
    from flask import request
    from flask import render_template
    from flask import redirect
    from flask import make_response

    app = Flask(__name__)


    @app.route(/login.html, methods=[GET, "POST"])
    def login():

        # 请求相关信息
        # request.method  提交的方法
        # request.args  get请求提及的数据
        # request.form   post请求提交的数据
        # request.values  post和get提交的数据总和
        # request.cookies  客户端所带的cookie
        # request.headers  请求头
        # request.path     不带域名,请求路径
        # request.full_path  不带域名,带参数的请求路径
        # request.script_root  
        # request.url           带域名带参数的请求路径
        # request.base_url        带域名请求路径
        # request.url_root      域名
        # request.host_url        域名
        # request.host            127.0.0.1:500
        # request.files
        # obj = request.files[‘the_file_name‘]
        # obj.save(‘/var/www/uploads/‘ + secure_filename(f.filename))

        # 响应相关信息
        # return "字符串"
        # return render_template(‘html模板路径‘,**{})
        # return redirect(‘/index.html‘)
        #return jsonify({‘k1‘:‘v1‘})

        # response = make_response(render_template(‘index.html‘))
        # response是flask.wrappers.Response类型
        # response.delete_cookie(‘key‘)
        # response.set_cookie(‘key‘, ‘value‘)
        # response.headers[‘X-Something‘] = ‘A value‘
        # return response
        return "内容"

    if __name__ == __main__:
        app.run()

 

以上是关于Flask基础知识的主要内容,如果未能解决你的问题,请参考以下文章

12_关于flask中的宏

Flask之模板之宏继承包含

Flask模板宏的概念和基本使用

python flask 基础入门

flask基础知识

flask知识汇总