Flask安装及入门操作

一、Flask和Django区别


  • Django:重武器,内部包含了非常多的组件:ORM、Form、ModelForm、缓存、Session、中间件、信号等…

  • Flask:短小精悍,内部没有太多组件。第三方组件非常丰富。路由毕竟特殊:基于装饰器来实现,但是究其本质还是通过add_url_rule来实现

二、Flask安装


Python版本:python3.6
Flask版本:Flask-1.0.2
百度网盘链接: https://pan.baidu.com/s/1lIT1F7_f4cKF88Rf0EJ4Fg 提取码: rnku

1、依赖安装

(1)pytz安装

下载地址:https://pypi.org/project/pytz/#files

[root@python ~]# wget https://files.pythonhosted.org/packages/af/be/6c59e30e208a5f28da85751b93ec7b97e4612268bb054d0dff396e758a90/pytz-2018.9.tar.gz
[root@python ~]# tar xf pytz-2018.9.tar.gz 
[root@python ~]# cd pytz-2018.9/
[root@python pytz-2018.9]# python setup.py install

##### (2)Babel安装
>下载地址:https://pypi.org/project/Babel/#files

~~ ~~[root@python ~]# wget https://files.pythonhosted.org/packages/be/cc/9c981b249a455fa0c76338966325fc70b7265521bad641bf2932f77712f4/Babel-2.6.0.tar.gz~~ ~~[root@python ~]# tar xf Babel-2.6.0.tar.gz~~ ~~[root@python a~]# cd Babel-2.6.0/~~ ~~[root@python Babel-2.6.0]# python setup.py install~~ ~~

(2)Jinja2安装

下载地址:https://pypi.org/project/Jinja2/#files

[root@python ~]# wget https://files.pythonhosted.org/packages/56/e6/332789f295cf22308386cf5bbd1f4e00ed11484299c5d7383378cf48ba47/Jinja2-2.10.tar.gz
[root@python ~]# tar xf Jinja2-2.10.tar.gz 
[root@python ~]# cd Jinja2-2.10/
[root@python Jinja2-2.10]# python setup.py install
(3)click安装

下载地址:https://pypi.org/project/click/#files

[root@python ~]# wget https://files.pythonhosted.org/packages/f8/5c/f60e9d8a1e77005f664b76ff8aeaee5bc05d0a91798afd7f53fc998dbc47/Click-7.0.tar.gz
[root@python ~]# tar xf Click-7.0.tar.gz 
[root@python ~]# cd Click-7.0/
[root@python Click-7.0]# python setup.py install
(4)itsdangerous安装

下载地址:https://pypi.org/project/itsdangerous/#files

[root@python ~]# wget https://files.pythonhosted.org/packages/68/1a/f27de07a8a304ad5fa817bbe383d1238ac4396da447fa11ed937039fa04b/itsdangerous-1.1.0.tar.gz
[root@python ~]# tar xf itsdangerous-1.1.0.tar.gz 
[root@python ~]# cd itsdangerous-1.1.0/
[root@python itsdangerous-1.1.0]# python setup.py install
(5)MarkupSafe安装

下载地址:https://pypi.org/project/MarkupSafe/#files

[root@python ~]# wget https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz
[root@python ~]# tar xf MarkupSafe-1.1.1.tar.gz 
[root@python ~]# cd MarkupSafe-1.1.1/
[root@python MarkupSafe-1.1.1]# python setup.py install
(6)Werkzeug安装

下载地址:https://pypi.org/project/Werkzeug/#files

[root@python ~]# wget https://files.pythonhosted.org/packages/72/60/f628e8920cbf54afa2a83b75b32a1e69b559b95514d1deb841823dd97830/Werkzeug-0.15.1.tar.gz
[root@python ~]# tar xf Werkzeug-0.15.1.tar.gz 
[root@python ~]# cd Werkzeug-0.15.1/
[root@python Werkzeug-0.15.1]# python setup.py install

2、安装Flask

下载地址:https://pypi.org/project/Flask/1.0.2/#files

[root@python ~]# wget https://files.pythonhosted.org/packages/4b/12/c1fbf4971fda0e4de05565694c9f0c92646223cff53f15b6eb248a310a62/Flask-1.0.2.tar.gz
[root@python ~]# tar xf Flask-1.0.2.tar.gz 
[root@python ~]# cd Flask-1.0.2/
[root@python Flask-1.0.2]# python setup.py install

3、测试

[root@python ~]# python 
Python 3.6.0 (default, Jan  8 2019, 05:27:57) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from flask import Flask              ###导入没有报错即可

三、werkzeug和wsgi二种方式


1、wetkzeug方式

#!/usr/bin/env python
#coding:utf-8
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('10.10.10.111',8000,hello)            ###这里的IP是本机IP

运行后访问:

http://10.10.10.111:8000/

2、wsgiref方式

#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server

def runserver(environ, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [bytes('

Hello world

',encoding='utf-8'),] if __name__ == '__main__': httpd = make_server('10.10.10.111',8000,runserver) ###这里的IP是本机IP httpd.serve_forever()

运行后访问:

http://10.10.10.111:8000/

上面二种方式的本质都是通过Socket来实现的!!!

四、基本使用


1、Flask说明

#!/usr/bin/env python
#coding:utf-8

from flask import Flask
### 实例化Flask对象
app = Flask(__name__)

### 将'/'和函数index的对应关系添加到路由中
@app.route('/')
def index():
    return 'Hello World'

if __name__ == "__main__":
    ### 监听用户请求
    ### 如果有用户请求的到来,则执行app的__call__方法
    ### app.__call__
    app.run()

2、登陆页面

(1)配置login.py
[root@python Flask]# vim login.py
#!/usr/bin/env python
# coding:utf-8
from flask import Flask, render_template, request, redirect, session, url_for
import os
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)
app.debug = True      ###修改代码后自动重启
Users = {
    1:{"name":"dream","age":20,"gender":"男", "text":"11111111111"},
    2:{"name":"dreamya","age":21,"gender":"男", "text":"222222222"},
    3:{"name":"dreamya1","age":23,"gender":"女", "text":"33333333"},
}

@app.route('/detail/', methods=['GET',])
def detail(nid):
    user = session.get('user_info')
    if not user:
        ### 实现网址的别名,通过url_for,反向生成
        url = url_for('l1')
        return redirect(url)

    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')
    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:
        user = request.form.get('user')
        pwd = request.form.get('pwd')
        if user == 'dream' and pwd == '1':
            session['user_info'] = user
            return redirect('/index')
        return render_template('login.html', error='用户名或密码错误')

if __name__ == '__main__':
    ### host写自己本机的IP
    app.run(host='10.10.10.111', port=8000)
(2)配置HTML

默认的HTML发布目录在templates中!!!

<1> 配置login.html

[root@python Flask]# vim templates/login.html



    
    login


用户登陆

{{ error }}

<2> 配置index.html

[root@python Flask]# vim templates/index.html



    
    index


用户详情

{% for k,v in user_dict.items() %} {% endfor %}
{{ k }} {{ v.name }} {{ v['name'] }} {{ v.get('name') }} 查看详情

<3> 配置detail.html

[root@python Flask]# vim templates/detail.html



    
    详情


    

详情 {{ info.name }}

{{ info.text }}

3、运行后测试结果

[root@python Flask]# python login.py
http://10.10.10.111:8000/login

Flask安装及入门操作_第1张图片

五、配置文件


1、方式一

app.debug = True                ###这种设置方法也只有个别的可以使用
app.config['debug'] = True      ###config的本质是个字典,可以通过app.config.update(...)

2、方式二

(1)from_pyfile
app.config.from_pyfile("python文件名")
eg:
	settings.py                               ###同级目录下新建目录
	    DEBUG = True
	    
	app.config.from_pyfile('settings.py')     ###从此文件中导入配置
(2)from_object
app.config.from_object('python的类或类的路径')  ###常用
eg:
	settings.py                               ###同级目录下新建目录,通过对父类的继承实现修改及默认配置
		class Config(object):
		    DEBUG = False
		    TESTING = False
		    DATABASE_URI = 'sqlit://:test:'

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

		class DevelopmentConfig(Config):
		    DEBUG = True
		
		class TestingConfig(Config):
		    TESTING = True
		    
	app.config.from_object('settings.DevelopmentConfig')

3、解耦和发送邮件/短信

伪代码:

可以直接修改settings.py文件实现对发送通道的开启,Base实现必须要写send方法,进行约束。

[root@python Flask]# pwd
/Python/Flask
[root@python Flask]# vim app.py
from flask import Flask,request
from Flask.utils.message import send_msgs
import os
app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)

@app.route('/')
def index():
    data = request.query_string.__get__('val')
    if data == 'xxx':
        send_msgs("xxxxx")
    return "xxx"

if __name__ == '__main__':
    app.run()
[root@python Flask]# vim settings.py
MSG_LIST = [
    "utils.message.eamil.Email",
    "utils.message.mas.Msg",
]
[root@python Flask]# mkdir -p utils/message
[root@python Flask]# vim utils/message/__init__.py
from Flask import settings
import importlib

def send_msgs(msg):
    for path in settings.MSG_LIST:
        m, c = path.rsplit('.', maxsplit=1)
        md = importlib.import_module(m)
        obj = getattr(md, c)()
        obj.send(msg)
[root@python Flask]# vim utils/message/base.py 
class Base(object):
    def send(self):
        raise NotImplementedError('xxx')
[root@python Flask]# vim utils/message/email.py
from .base import Base
class Email(Base):
    def __init__(self):
        self.username = "xxx"
        self.pwd = "xxx"

    def send(self, msg):
        pass
[root@python Flask]# vim utils/message/msg.py
from .base import Base
class Msg(Base):
    def __init__(self):
        self.username = 'xxx'
        self.pwd = 'xxx'

    def send(self, mas):
        pass

六、路由系统


1、路由运行原理

#!/usr/bin/env python
# coding:utf-8
from flask import Flask
import os

app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)

"""
route函数中可以发现:
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)
"""

@app.route("/", methods=['GET', 'POST'], endpoint='n1')
def index():
    return 'Hello World!'

### 可以等效于下面的login写法
def login():
    return "logining..."

app.add_url_rule('/login/', 'n2', login, methods=['GET', 'POST'])

if __name__ == '__main__':
    app.run(host="10.10.10.111")

2、路由CBV写法

#!/usr/bin/env python
# coding:utf-8
from flask import Flask, views
import os
app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)
def auth(fun):
    def inner(*args, **kwargs):
        res = fun(*args, **kwargs)
        return res
    return inner

class IndexView(views.MethodView):
    methods = ["GET"]
    decorators = [auth, ]
    def get(self):
        return "Index.GET"

app.add_url_rule("/index", view_func=IndexView.as_view(name='index'))
if __name__ == '__main__':
    app.run(host="10.10.10.111")

运行后访问:

http://10.10.10.111:5000/index

3、@app.route和app.add_url_rule参数

rule                         ###URL规则
view_func                    ###视图函数名称
defaults=None                ###默认值,defaults={'k','v'}
endpoint=None                ###用于反向生成URL(别名),url_for('别名')
methods=None                 ###允许请求方式,['GET','POST']
strict_slashes=None          ###URL最后加和不加/都可以访问(默认),True:严格按照写的地址访问
redirect_to=None             ###重定向到执行地址
subdomain=None               ###子域名访问

subdomain参数:

#!/usr/bin/env python
# coding:utf-8
from flask import Flask, views
import os
app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)
app.config['SERVER_NAME'] = "dreamya.com:5000"

@app.route("/",subdomain="dream")
def index():
    return "dream..."
    
@app.route("/login",subdomain="")
def username_login(username):
    return username + ".login..."

if __name__ == '__main__':
    app.run(host="10.10.10.111")
###windows:win10(C:\Windows\System32\drivers\etc\hosts),此方式可通过浏览器访问
[root@python ~]# vim /etc/hosts        ###在末尾加入
10.10.10.111      www.dreamya.com  
10.10.10.111      dream.dreamya.com

windows中直接浏览器访问网址即可!!!

在这里插入图片描述

4、路由系统

(1)默认路由
- @app.route('/user/')
- @app.route('/post/')
- @app.route('/post/')
- @app.route('/post/')
- @app.route('/login', methods=['GET', 'POST'])

五种路由系统都是基于一下对应关系来处理:

DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}
(2)正则路由

<1> 直接路由

#!/usr/bin/env python
# coding:utf-8
from flask import Flask, views, url_for
from werkzeug.routing import BaseConverter
import os
app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)

class RegexConverter(BaseConverter):
    """
    自定义URL匹配正则表达式
    """
    def __init__(self,map,*args):
        super(RegexConverter,self).__init__(map)
        
### 将自定义转换器添加到转换器字典中,并指定转换器使用时名字为: reg
app.url_map.converters['reg'] = RegexConverter

@app.route('/index/')
def index(nid):
    return nid
    
if __name__ == '__main__':
    app.run(host="10.10.10.111")

运行后访问:

http://10.10.10.111:5000/index/7           ###后面的数字可以自定义

<2> 通过函数实现路由

#!/usr/bin/env python
# coding:utf-8
from flask import Flask, views, url_for
from werkzeug.routing import BaseConverter
import os
app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)

class RegexConverter(BaseConverter):
    """
    自定义URL匹配正则表达式
    """
    def __init__(self,map,*args):
        super(RegexConverter,self).__init__(map)
        self.regex = args[0]

    def to_python(self, value):
        """路由匹配成功后传递给视图函数中参数的值"""
        return int(value)

    def to_url(self, value):
        """
        使用url_for反向生成URL时,传递的参数经过该方法及
        逆行处理,返回的值用于生成URL中的参数
        """
        val = super(RegexConverter,self).to_url(value)
        return val

### 将自定义转换器添加到转换器字典中,并指定转换器使用时名字为: reg
app.url_map.converters['reg'] = RegexConverter

@app.route('/index/')
def index(nid):
    return nid
    
if __name__ == '__main__':
    app.run(host="10.10.10.111")

七、模板


默认是防止XSS攻击,我们可以通过safeMarkup方式来显示模板,Markup方式和Django中的mark_safe相同!!!

1、safe

#!/usr/bin/env python
# coding:utf-8
from flask import Flask, render_template
import os
app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)

def fun(arg):
    return "" % (arg,)

@app.route('/')
def index():
    return render_template('index.html', func=fun)

if __name__ == '__main__':
    app.run(host="10.10.10.111")

配置HTML:

[root@python Flask]# vim templates/index.html 



    
    


	{{ func("yaya") }}
    {{ func("yaya")|safe }}


2、 Markup

#!/usr/bin/env python
# coding:utf-8
from flask import Flask, render_template, Markup
import os

app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)

def fun(arg):
    return Markup("" % (arg,))

@app.route('/')
def index():
    return render_template('index.html', func=fun)

if __name__ == '__main__':
    app.run(host="10.10.10.111")

配置HTML:

[root@python Flask]# vim templates/index.html 



    
    


	{{ func("yaya") }}


3、宏定义

#!/usr/bin/env python
# coding:utf-8
from flask import Flask, render_template, Markup
import os

app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)

def fun(arg):
    return Markup("" % (arg,))

@app.route('/')
def index():
    return render_template('index.html', func=fun)

if __name__ == '__main__':
    app.run(host="10.10.10.111")

配置HTML:

[root@python Flask]# vim templates/index.html 



    
    


    {{ func("yaya") }}
    {% macro xx(name, type='text', value='') %}
        
        
    {% endmacro %}
    {{ xx('dream') }}


八、请求和响应


from flask import Flask, request, render_template, redirect, make_response
app = Flask(__name__)

@app.route('/login.html', methods=['GET', "POST"])
def login():
    ### 请求相关信息
    # request.method
    # request.args
    # request.form
    # request.values
    # request.cookies
    # request.headers
    # request.path
    # request.full_path
    # request.script_root
    # request.url
    # request.base_url
    # request.url_root
    # request.host_url
    # request.host
    # 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')

    # 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()

九、Session简单使用


#!/usr/bin/env python
# coding:utf-8
from flask import Flask, session
import os
app = Flask(__name__)
app.debug = True
app.secret_key = os.urandom(24)

@app.route('/')
def index():
    ### Flask内置使用加密cokkie(签名cookie)来保存数据
    session['k1'] = 'v1'
    session['k2'] = 'v2'
    return "index"

if __name__ == '__main__':
    app.run(host="10.10.10.111")

下一篇文章>Flask入门(一)之消息闪现、请求扩展、中间件、蓝图、上下文管理

你可能感兴趣的:(Flask)