web開發框架Flask學習一

flask框架
    用Python作Web開發的三大框架特色
        Django
            主要特色是大而全,集成了不少的組件,例如:Admin Form Model等,無論你用不用的到,他都會爲
            你提供,一般用於大型Web應用,因爲內部組件足夠強大,因此使用Django能夠作到一鼓作氣,
           Django的優勢是大而全,缺點也就露出來,這麼多的資源一次性所有加載,確定會形成cpu資源的浪費
        
        flask
            flask原生組件幾乎爲零,只有底層的jinja2(模板)和Werkzeug(服務器),屬於短小精悍型框架,
            flask一般用於小型應用和快速構建應用,其強大的第三方庫足以支持一個大型項目

        Tornado
            主要特色是原生異步非阻塞,在IO密集型和多任務處理上佔據壓倒性的優點,屬於專一性框架,通
            經常使用於API後端應用,遊戲服務後臺,其內部實現的異步非阻塞真的是很穩,優勢是異步,缺點是乾淨,連個session也不支持
            
    什麼是flask的框架
        web訪問流程
        web框架
        flask簡介    
    建立flask的虛擬環境
        windos下用pycharm建立flask的虛擬環境
        windows下,直接在user目錄中建立一個pip目錄,如:C:\Users\xx\pip,新建文件pip.ini
        內容以下
             [global]
             index-url = https://pypi.tuna.tsinghua.edu.cn/simple
        利用pycharm的優勢自動建立虛擬環境    
        
    寫模板程序
        from flask import Flask

        app = Flask(__name__)

        @app.route("/")
        def index():
            return "hello word"

        if __name__ == "__main__":
            app.run(port=9001, debug=True)
        
    Flask參數的配置
        import_name,              #至關於 __name__/"__main__"
        static_path=None,           #靜態路徑
        static_url_path=None,         #規定了哪一種類型的url是靜態請求
        static_folder='static',       #若是是靜態請求,去static文件夾找文件
        template_folder='templates',    #靜態模板,去templates中找模板文件
        instance_path=None,           #論壇 
        instance_relative_config=False   #應用程序的配置
        
    加載配置的方式
        DEBUG = True  設置爲調試模式
        app.config.from_object()
            從對象中加載
                class Config(object):
                    DEBUG = True
                app.config.from_object(Config)    
            從配置文件中加載
                從config.ini文件中加載的內容爲
                    DEBUG = True
                app.config.from_object("config.ini")
            從環境變量中加載(不推薦使用)
        經常使用配置的參數 
            app.debug = True
            app.config["DEBUG"] = True
            
    app.run()的三個參數
        host="127.0.0.1"
        port=9001
        debug = True
            
    JSON的數據格式
        json中的數據必定要加雙引號("")
        json中的數據實際就是一種在特定格式下顯示的字符串
        json中的數據通常是POST請求方式
        json經常使用的方法
            json.dump()
            json.dumps()   #將字典對象轉化爲標準格式的json字符串,沒有格式化(按照代碼中定義的json格式)
            json.load()
            json.loads()    #將json格式的字符串轉化爲Python對象(字典)
            jsonify()       #將字典對象轉化爲標準格式的json字符串,格式化顯示 
        若是JSON數據中有中文,在瀏覽器顯示是unicode編碼,需設置以下:
            #將默認的ASCII編碼屏蔽掉,才能在瀏覽器中顯示當前json數據中的具體內容
            app.config["JSON_AS_ASCII"] = False
            
             json_data = {
                "name": "張三",
                "age": 20,
                "gender": "男"
                }
        
    重定向(redirect)
        @app.route("/redirect")
        def func_redirect():
            #跳轉到百度等其餘網頁
            #return redirect("http://www.baidu.com")

            #跳轉到當前路徑下的某個文件
            return redirect(url_for("要跳轉的函數名",是否攜帶參數))
            
    提供模板文件(render)
        在當前路徑中必許有一個文件夾叫templates,其中存放html中的模板代碼,不然會有一個
        jinja2.exceptions.TenplatesNotFound的錯誤
        @app.route("/home")
        def home():
            return render_template("/test.html")  //直接跳轉到test.html視圖中
        
    自定義狀態碼
        如何自定義狀態碼
            @app.route('/login')
            def func():
                return 'login',666  #其實是一個元祖,猶如 return("login",666)
    
    路由的參數配置
        url中參數的定義
            尖括號(<int:result>)中存放的是轉換器和參數,參數的名稱以及對參數類型的限制
        請求類型的指定
            默認是GET的請求模式
            app.route("",methods=["GET","POST"])   #app.route()定義規則
            用request.method獲取當前請求,查看當前請求是那種請求方式
            
    自定義轉換器
        自定義一個類繼承BaseConverter
        重寫父類的regex變量
        在app.url_map.converters這個字典中增長一組當前所定義的轉換器數據(本身定義名字)
        像使用int轉換器同樣的使用它

     讓自定義的轉換器可以接收參數
          自定義一個類繼承BaseConverter
          用super重寫init方法,在init方法中須要有url_map這個參數以及正則表達式的參數*args,這個參數是咱們在使用轉換器的時候咱們本身傳遞過來的
          在app.url_map.converters這個字典中增長一組當前所定義的轉換器數據
          @app.route("/demo/<re(r'a[0-9]{6}'):uname>")
        
      BaseConverter中的其餘兩個參數的執行時機    
       轉換器to_python
              匹配和調用的前後順序:必定是先匹配,再調用視圖函數
              to_python調用的時機:匹配了url以後,在調用視圖函數以前
              to_python的做用:用來決定視圖函數中的參數的值

          轉換器to_url
              to_url是給url_for這個函數使用
              做用:決定url_for 中咱們傳遞的參數,最終的地址欄中所呈現出來的狀態
    
    請求錯誤的處理方式
        主動拋出狀態碼(abort)
        統一處理錯誤(@app.errorhandler(404/500/Exception))
    
@app.route("/")
        def index():
            return "hello word"

        @app.route("/login")
        def func_login():
            result = 4/0
            abort(404)
            return "login......"

        @app.route("/register")
        def func_register():
            result = 100 + "111"
            abort(500)
            return "regsit......"

        @app.errorhandler(ZeroDivisionError)
        def errorhandler(e):
            return "除數不能爲0"

        @app.errorhandler(TypeError)
        def errorhandler(e):
            return "整型和字符型的數據不能進行運算"

        @app.errorhandler(404)
        def func_browser(e):
            return "瀏覽器正在更新,請稍等"

        @app.errorhandler(500)
        def func_server(e):
            return "服務器繁忙,請稍後"

        @app.errorhandler(Exception)
        def errorhandler(e):
            return "頁面正在加載,請稍後"

        if __name__ == "__main__":
            app.run(port=9001, debug=True)
View Code
    
鉤子函數(回調函數) before_first_request 時機: 在開啓服務器以後的第一次請求 before_request 時機: 每個請求以前 使用場景: 對請求統一進行處理,好比黑名單功能 綁定IP地址remote_addr=="192.168.15.60" after_request 時機: 每一次沒有報錯的請求以後 場景: 統一的對沒有報錯的響應進行響應頭信息增長,如: response.headers["Content-Type"] = "application/json" teardown_request 時機: 每一次請求以後,都會調用 場景: 對錯誤進行收集 request請求知識 獲取請求類型:request.method #獲取當前是哪種請求方式 獲取請求的ip地址:request.remote_addr #訪問IP地址 獲取請求的數據: request.args.get("xxx") #GET請求數據 獲取URL中的參數 request.form.get("xxx") #POST請求數據 獲取form表單中的數據 request.files.get("xxx") #獲取文件數據 list(request.form.keys("name","pwd")) request.values.get("user") #取不到返回None request.values["user"] #直接取用戶名 request.values.to_dict() #獲取當前表單提交中的全部數據 request.data() #request是基於mimetype進行處理的 request.headers() print(type(request.headers)) """ Host: 127.0.0.1:5000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Referer: http://127.0.0.1:5000/home Content-Type: application/x-www-form-urlencoded Content-Length: 26 Cookie:csrftoken=vDIozqveCEfArdYXlM6goHVlSQEn7h4bDygNphL2Feas60DiM2di0jlqKfxo7xhA Connection: keep-alive Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0 """ #獲取當前的url路徑 print(request.path) #/req # 當前url路徑的上一級路徑 print(request.script_root) # 當前url的所有路徑 print(request.url) # http://127.0.0.1:5000/req # 當前url的路徑的上一級所有路徑 print(request.url_root ) # http://127.0.0.1:5000/ 注意事項 若是url和form中的Key重名的話,form中的同名的key中value會被url中的value覆蓋 #http://127.0.0.1:5000/req?id=1&user=20 print(request.values.to_dict()) #{'user': 20 'pwd': 'DragonFire', 'id': '1'} 請求參數攜帶參數的幾種方式 一、http://127.0.0.1/login/zhangan/123456          #直接在地址欄中輸入 二、http://127.0.0.1/login?uname=zhangsan&upwd=123456   #利用GET請求 三、http://127.0.0.1/login                 #利用POST請求 uname=zhangsan&upwd=123456 狀態的保持 http默認是無狀態的,前一個請求和後一個請求之間是獨立的,這個是http協議的特性 基於他的這種特性,若是想讓不一樣請求之間能夠有關聯,須要引入cookie機制 設置cookie cookie是存儲在瀏覽器端的鍵值字符串,會伴隨着瀏覽器的自求自動提交到服務器,不一樣的網站不能共享cookie,保存在本地瀏覽器中安全性較低, 瀏覽器第一次發起登陸請求該網站時,,若是服務器檢測到帳號和密碼正確,就會給該請求設立一個cookie,瀏覽器會自動把cookie保存起來,
       下一次請求登陸時會把該cookie帶到服務器,服務器從當前請求中獲取當前所使用的cookie,根據cookie就能夠判斷當前是誰登陸
        
from flask import Flask, make_response, request
            app = Flask(__name__)

            # 存儲在客戶端
            @app.route("/")
            def index():
                user = request.cookies.get("user_name")
                id = request.cookies.get("user_id")
                return "%s---%s"%(user,id)

            @app.route("/login")
            def login():
                response = make_response("success")
                response.set_cookie("user_name", "zhangsan",max_age=3600)
                response.set_cookie("user_id", "2",max_age=3600)
                # return "success"
                return response

            @app.route("/logout")
            def logout():
                response = make_response("success")
                response.delete_cookie("user_name")
                response.delete_cookie("user_id")
                return response

            if __name__ == "__main__":
                app.run(port=9001, debug=True)
View Code
 
 
       設置session
            存儲在服務器上,對於敏感、重要的信息,建議要存儲在服務器端,不能存儲在瀏覽器中,如用戶名、餘額、等級、驗證碼等信息在服務器端進行狀態保持的方案就是session
            session依賴於cookie
from flask import Flask, session

            app = Flask(__name__)

            app.config["SECRET_KEY"] = "wxb"

            # 存儲在服務器上
            @app.route("/")
            def index():
                user_id = session.get("user_id", "")
                user_name = session.get("user_name", "")
                return "%s---%s"%(user_id,user_name)


            @app.route("/login")
            def login():
                session["user_name"] = "lisi"
                session["user_id"] = "1"
                return "success"

            @app.route("/logout")
            def logout():
                session.pop("user_name",None)
                session.pop("user_id",None)
                return "success"

            if __name__ == "__main__":
                app.run(port=9001, debug=True)
View Code
 
 

    上下文管理器(相似全局變量)
        請求上下文
            request  當請求發生時,調用視圖函數,觸發request.get()
            session     
            拋出異常  RuntimeError:working outside of request context
        應用上下文
            current_app              current_app.config.get("DEBUG")
            g變量           通常做用於跨py文件,先用g.num存取變量,在再另外一個py文件中取值
            拋出異常           RuntimeError:working outside of application context
            
    flask_script    
        pip install flask_script
        
        from flask import Flask
        flask_script import Manager
        app = Flask(__name__)
        manager = Manager(app)
        
        @app.route("/")
        def index():
            return "hello world"
        
        if __name__ == "__main__":
            manager.run(debug=True)
            
    flask中能夠return的幾種寫法
      1)return "字符串"
      2)return "字符串",666
      3)return redirect("/")
      4)response = make_response("字符串")
         response.set_cookie('username', username)
         return response
       5)return render_template("demo.html",mylist=["haha","hehe"])
       6)response = make_response(render_template("index.html"))
         response.set_cookie('username', username)
         return response
       7)response = redirect(url_for('transfer'))
         response.set_cookie('username', username)
         return response
相關文章
相關標籤/搜索