zoukankan      html  css  js  c++  java
  • flask框架-上

    flask简介

      Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。

      Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。

    为什么要从Flask开始学习web框架?

      依赖于wsgiref、jianjia2、wsgi、Werkzeug。

    """
    1.python语言的灵活性给予了Flask同样的特征;
    
    2.无论是用户画像还是产品推荐,python相比其他语言都有极大的优势;
    
    3.Flask轻便,容易上手,试错成本低
    """

    与其他web框架对比

    """(1)Django:比较“重”的框架,同时也是最出名的Python框架。包含了web开发中常用的功能、
    组件的框架(ORM、Session、Form、Admin、分页、中间件、信号、缓存、ContenType....),
    Django是走大而全的方向,最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就能自动生成数据库结构、以及全功能的管理后台。 (2)Tornado:大特性就是异步非阻塞、原生支持WebSocket协议; (3)Flask:如上 (4)Bottle:是一个简单高效的遵循WSGI的微型python Web框架。说微型,是因为它只有一个文件,除Python标准库外,它不依赖于任何第三方模块。
    """

    flask安装及使用

     目录结构

    通过别人的目录大致了解一下flask框架的目录结构

     初始化项目

    (1)、创建flask实例对象

    flask程序必须创建一个程序实例,常用的方法:

       这里的app就是一个程序实例,客户端(一般是浏览器)将请求发送给服务端Web服务器,Web服务器再把请求发给Flask实例。

    (2)构建实例对象从URL到python函数的映射关系

      程序实例需要知道所有URL对应的执行代码,所以要有从URL到python函数的映射关系。处理URL到python函数映射关系的程序一般叫做路由(Router)

    (3)启动服务器 

     开始测试hello world

    最简单的测试

     这是flask框架制作的一个最小的应用。使用python运行后访问localhost:5000就能看到网页显示Hello world。

      这里首先引入了Flask类,然后给这个类创建了一个实例,name代表这个模块的名字。因为这个模块是直接被运行的所以此时name的值是main。
    然后用route()这个修饰器定义了一个路由,告诉flask如何访问该函数。最后用run()函数使这个应用在服务器上运行起来。

    flask模板

     Flask的模板功能是基于Jinja2模板引擎实现的。让我们来实现一个例子吧。创建一个新的Flask运行文件(你应该不会忘了怎么写吧),代码如下:

     flask启动的本质

      flask依赖于两个模块的运行:werkzeug、wsgiref.

    wsgiref可以当做独立的server来运行。

    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('监听8011')
        myserver.serve_forever()

    werkzeug是WSGI工具包,它可以作为web框架的底层库

    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)

    结果

     flask启动的核心本质

    from flask import Flask
    
    app=Flask(__name__)
    
    # mvc.c  CBV
    @app.route('/')路由
    def index():
        return "back ok"
    
    if __name__ == '__main__':
        # 本质上run_simple(host,port,app,**options)
       # app(),对象加().执行__call__
       app.run()

    默认的启动ip和端口:

    flask的四剑客使用

    from flask import Flask,render_template,redirect,Response,jsonify
    
    app=Flask(__name__)
    
    @app.route('/')
    def text():
    
        # 1直接返回字符串
        # return "人生苦短,我学Python"
    
        # 2返回html
        # name_dict = {"name":'Eason'}
        # return render_template("text.html",name="java",name_dict=name_dict)

    #跳转页面 # return redirect("/login") # 返回json数据 name_dict = {{"name":"jack"},{'hobby':"music"}} @app.route('/login') def login(): return "Hello woorld" if __name__ == '__main__': app.run()

    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 %}
    
    </body>
    </html>

    flask配置文件的4种方式

      只要配置之后,Ctrl+s保存,即可实现重启服务器生效的作用。

    from  flask import Flask
    app=Flask(__name__)
    #配置文件1,这中方式只能配置两种 # app.debug=True # app.secret_key="123123" #第二种,以字典的形式 # app.config['DEBUG']=True

    #第三种,以文件的形式 # app.config.from_pyfile("settings.py") #第四种以类的形式(推荐) settings.py文件下自定义的类。 app.config.from_object('settings.DevelopmentConfig')
    @app.route(
    '/login') def login(): print(123) return "ojbk_login" if __name__ == '__main__': app.run()

    settings.py

    # DEBUG = True
    
    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

    其他配置方式,有哪些配置,了解即可。

     {
     2         'DEBUG':                                get_debug_flag(default=False),  是否开启Debug模式
     3         'TESTING':                              False,                          是否开启测试模式
     4         'PROPAGATE_EXCEPTIONS':                 None,                          
     5         'PRESERVE_CONTEXT_ON_EXCEPTION':        None,
     6         'SECRET_KEY':                           None,
     7         'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
     8         'USE_X_SENDFILE':                       False,
     9         'LOGGER_NAME':                          None,
    10         'LOGGER_HANDLER_POLICY':               'always',
    11         'SERVER_NAME':                          None,
    12         'APPLICATION_ROOT':                     None,
    13         'SESSION_COOKIE_NAME':                  'session',
    14         'SESSION_COOKIE_DOMAIN':                None,
    15         'SESSION_COOKIE_PATH':                  None,
    16         'SESSION_COOKIE_HTTPONLY':              True,
    17         'SESSION_COOKIE_SECURE':                False,
    18         'SESSION_REFRESH_EACH_REQUEST':         True,
    19         'MAX_CONTENT_LENGTH':                   None,
    20         'SEND_FILE_MAX_AGE_DEFAULT':            timedelta(hours=12),
    21         'TRAP_BAD_REQUEST_ERRORS':              False,
    22         'TRAP_HTTP_EXCEPTIONS':                 False,
    23         'EXPLAIN_TEMPLATE_LOADING':             False,
    24         'PREFERRED_URL_SCHEME':                 'http',
    25         'JSON_AS_ASCII':                        True,
    26         'JSON_SORT_KEYS':                       True,
    27         'JSONIFY_PRETTYPRINT_REGULAR':          True,
    28         'JSONIFY_MIMETYPE':                     'application/json',
    29         'TEMPLATES_AUTO_RELOAD':                None,

    路由系统

    @app.route('/xxx/<username>')
    @app.route('/xxx/<int:id>')
    @app.route('/xxx/<float:id>')
    @app.route('/xxx/<path:path>')
    @app.route('/xxx', methods=['GET', 'POST'])

    @app.route本质,源码分析

     内部源码add_url_rule,所需要传的参数:view_func、endpoint....

     代码演示

    from flask import Flask,url_for
    app=Flask(__name__)
    app.debug=True
    
    @app.route('/login',methods=['POST','GET'],endpoint="test")
    #decorator
    def login(nid):
        print(type(nid),nid)
        return "obi_login"
    
    # rule 就是路由
    # enpoint,取别名,如果没有就用当前的函数名
    # enpoint,不能重复
    # methods=["POST","GET"]
    
    # view_func 就是我们enpoint,指向的函数,也就是请求该路由的时候,要响应函数
    # app.add_url_rule(rule,'取别名,反向解析,login')
    app.add_url_rule('/login/<strnig:nid>',view_func=login,endpoint="func",methods=["POST","GET"])
    
    """
    取别名:
    """
    #app01.route('/',endpoint="func")
    
    def index():
        real_url = url_for("test")
        return real_url
    
    app.add_url_rule('/index',view_func=index,methods=["POST","GET"])
    
    if __name__ == '__main__':
        app.run()

     method=[],如果不传参数,默认是视图类,可以只传POST/GET.

    路由默认的转换器,有名分组支持的数据类型

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

    初识flask中的CBV视图

    cbv视图类的基本写法

    #第一种方法
    class IndexView(views.View):
        methods = ['GET']
        decorators = [auth, ]
    
        def dispatch_request(self):
            print('Index')
            return 'Index!'
    
    app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  
    #第二种方法(通常使用这种) class IndexView(views.MethodView): methods = ['GET','POST'] #指定可以接收的方法有什么,默认可以不写 decorators = [auth, ] #指定自定义的装饰器 def get(self): return 'Index.GET' def post(self): return 'Index.POST' app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))

    总结流程:

    1.先从flask中导入views

    2.写一个类一定要继承views.MethodView

    3.在类中写methods = ['GET','POST'],可以指定可接受的请求类型,默认是两种都行

    4.在类中写decorators = [auth,]可以指定装饰器,第一个装饰器是最里层函数依次往外包裹

    5.在类中写def get(self):用于获取get请求

    6.在类中写def post(self):用于获取post请求

    7.添加路由的方法使用

    app.add_url_rule('路由', view_func=IndexView.as_view(name='自定义一个端点名字'))  

      其原理是IndexView.ad_view(name='自定义名字')会返回一个函数,name是为这个函数命名,可以通过这个函数进行分发请求等操作。

    #IndexView.as_view(name='index')都views.View里面的as_view的view
    #为什么要as_view(name='index'),
    #如果不指定,就都是view
    #所以必须指定

    CBV常用的模式

    继承的是:MethodView

    登录实现

    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):
        info = USERS.get(nid)
        return render_template('detail.html',info=info)
    
    @app.route('/index',methods=['GET'])
    def index():
        return render_template('index.html',user_dict=USERS)
    
    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':
                url=url_for('index')
                return redirect(url)
                # session['user_info'] = user
            return render_template('login.html', error='用户名或密码错误')
    app.add_url_rule("/login",view_func=login,methods=["GET","POST"])
    
    
    
    if __name__ == '__main__':
        app.run()
  • 相关阅读:
    750. 角矩形的数量(动态规划)
    Python中with标签的使用详解
    GraalVM
    spring 源码解析(二) 2.下载源码,及错误的排除。
    spring 源码解析(一) spring的架构
    词典
    java日志框架 (五)
    java日志框架 (四) 日志相关
    java日志框架 (三) 日志框架使用 之 SLF4J + Log4j2
    java日志框架 (二) 日志框架使用 之 SLF4J + logback
  • 原文地址:https://www.cnblogs.com/Gaimo/p/11837344.html
Copyright © 2011-2022 走看看