flask2

flask2 & get方法

-1 裝飾器

def war(func):
    def inner(*args,**kwargs):
        if session.get('username'):
            ret = func(*args,**kwargs)
            return ret
    return inner
@app.route('/detail')   
@war        #執行inner --> func()   - return ret  war(detail)  --> inner
def detail():
    return ....

-1.1 不一樣的函數用裝飾器,拋出異常

error: function mapping is overwriting an existing endpoint function :innercss

源碼: def route(self,rule,**options)  #第一個參數app  /detail    {}

    def decorator(f) :   f = def details
        end  =  options.pop('end',None)         #None
        
        
在代碼    app.add_url_rule(rule,end,f,**options)# '/detail'  None   def detail  {}     #本質上是執行這句話
    if end is None:
        end = _end_from_view_func(view_func)    #裏面 return view_func.__name__ #return 'details'
        
        #assert 斷言   view_func.__name__ is not None 
                    
    options['end'] = end        #{}  -->  {'end':‘detail’}
    methods = options.pop('methods',None)       #沒有返回空
    
    if methods is None:
        methods = getattr(view_func,'methods',None) or ('GET',)
    
    methods = set(item.upper() for item in methods) #集合去重
    
    if view_func is not None: 
        old_func = self.view_functions.get(end) #v_f 全部的視圖函數
        if old_fun is not None and old_func! = view_func:
            raise AssertionError()
        self.view_functions[end] = view_func
                        #view_function = {'details':deatils}
        
2 新的op =  {'methods' : ['GET','get','Get']}     帶過去


    if old_fun is not None and old_func! = view_func: # 老innner的內存地址和新inner的內存地址   detail 和 deatils
    
    
解決方法:(不會出現重名不一樣函數的現象)
1
if end is None:
                end = option 
給endpoints = 傳參 不爲None

2  from  functools import  wraps    #返回原來的函數名
def war(func):          #裝飾器
    @wraps(func)        #利用偏函數的原理

爲多個視圖函數增長同一個裝飾器html

1 Flask 中的路由

參數:前端

​ endpoint 映射路由-視圖函數__name__ = ''(字符串)nginx

@   endpoint='loginasdf'
def login():
    print(url_for('loginasdf'))         #login

​ methods = []/() #--> 集合set(xxx.lower )數據庫

​ #當前視圖函數支持的請求方法 405 請求方式不被容許 defaults = {'id':1} #默認參數 一旦默認參數存在,視圖函數必須有一個形參去接收,形參變量名必須與defaults中的一致django

​ strict_salshes = False/True #是否嚴格遵循路由匹配(默認是true)json

​ redirect_to = '/login' #308(環境問題301有時) 永久重定向 不通過視圖函數的(不浪費那塊空間) (老頁面新頁面)flask

​ 動態參數路由緩存

​ #分頁session

​ route('details/int: /int: /int: /')

​ print(page,page1,page2) #傳參 (必須是定長的傳三個)

​ route('details/int: /')

​ route('details/string: /') 什麼都不寫 默認string

​ #經過路由地址訪問文件

​ /s1.py url地址

​ def detail(folder,filename) #folder 跨目錄

​ #寫url /template/xx.html(前面是。。/後面對應)

​ fp=os.path.join(folder,filename)

​ return send_file()

2 .Flask中的配置

  1. 初始化配置
    app = Flask(__name__,template_folder='templatess',static_folder='statics',static_url_path='/static') #存放路徑 /開頭:路由地址

    static_folder='statics'   #靜態文件存放路徑  
    static_url_path='/static' #靜態文件訪問路徑  - 默認/ + folder
    static_host = None,        #訪問這,去另外一個主機去拿
    host_matching=False,   #定義的是ip/域名 只能按定義的匹配   
    subdomain_matching=False, #car子域名www主域名
     nginx 能夠阻攔域名 子域名(替代分發)上兩個
  2. config 對象配置

app.config['DEBUG'] = True

app.config #第三方組件 environment 都在這裏

DEBUG --- 編碼階段
代碼重啓(大多數)日誌輸出級別很低(查錯看到error:扔到數據庫記上) (大量日誌(銀行)存到緩存(速度太快))
頁面種會顯示錯誤 錯誤代碼(沒testing,關了debug,自動開啓testing)

TESTING --- 測試階段 日誌輸出級別較高 不重啓 無限接近線上環境

"SECRET_KEY": None,     #不同 可能加連個md5   
             SECRET_KEY = hashlib.md5(b'12352344553').hexdigest()
SERVER_NAME             #至關於域名
SESSION_COOKIE_NAME
SESSION_COOKIE_DOMAIN   #在那個域名下配置
SESSION_COOKIE_PATH     #在那個個環境
SESSION_COOKIE_HTTPONLY
JSONIFY_MIMETYPE        #本身作反爬  (隨便改的話下載的)
make_config
    default_config      
        {'ENV','DEBUG':(不能在這裏改)}

app.default_config      #能夠查詢 忘了
<img src="/static/2.jpg">       #
{#路由地址  不是靜態文件訪問的地址#}
staic_floader = 'static'

app.config['TESTING'] = True

* Debug mode: off
127.0.0.1 - - [11/Jul/2019 11:01:01] "GET /statics/2.jpg HTTP/1.1" 404 -

運維開發都是你,測試也是你的話

那樣,成長速度很快
app.config['JSONIFY_MIMETYPE']  = '2534ijij/isjiga'
@app.route('/bab')
def bab():
    return {'k':1} #封裝了 jsonify         #會下載

from_object

for key in dir(obj):        #把每一個變成字典
  if key.isupper():         
                self[key] = getattr(obj, key)   #slef = config
    ...
    config['DEBUG']  = True

config 寫的 均可以序列化
s20 = 'NB'
SESSION_TYPE = 'Redis'

名言

不要把時間浪費在路上 ----哪一個名人

3 flask 藍圖

當成是 一個不能被run的flask對象
做用:應用隔離,不用註銷了

serv --
--users.py

from flask import Blueprint

#不能被 run的       一個flask 藍圖惟一個標識
user = Blueprint('user',__name__)   # template_folder = 'serv/user'
                                # 均可以和flask對象差很少init封裝
@user.route('/get_user',methods=['GET','post']) #大小寫都行
def get_user():
    return "I am Users Blueprint"

藍圖沒有 run , 由於沒有config(run 基於 config)

from flask import Flask
from serv.users import user

app = Flask(__name__)

app.register_blueprint(user)    #註冊藍圖

if __name__ == '__main__':
    app.run()

藍圖是須要註冊在app實例上的 app.register_blueprint(bp對象)

藍圖共享app.config

訪問網頁所有都登錄
100多個藍圖

4 . Flask 特殊裝飾器

@app.before_request     #請求進入視圖函數以前
def be1():
    print('be1')
    return None

    #return ‘出錯了’  #be1 af2 af1
@app.before_request
def be2():
    print('be2')
    #return None
    return ‘出錯了’

django是一個請求一個響應

@app.after_request
def af1(res):
    print('af1')
    return res
@app.after_request
def af2(res):
    print('af2')
    return res

結果:

be1
be2
af2
af1

替代了session + 裝飾器
部分的很差用

@user.before_request
def look():
    print('user1')
    return '棍'
@user.after_request
def look(res):
    print('user2')
    return res
be1
be2
user2
af2
af1

1 .before_request 請求進入視圖函數以前進行處理 return None 繼續執行不然阻斷

2 .after_request 視圖函數結束 響應客戶端以前

正常週期 be1 2 3 - vf - af3 - af2 -af1

異常週期

3 errorhandler 重定向錯誤信息

3.1 有參數的裝飾器errorhandle(監聽錯誤狀態碼5xx 4xx int)
3.2 必須有一個形參接收 error_message

@app.errorhandler(404)      #監聽的端口在這
def error(error_message):
    print(error_message)
    # return '你要訪問的頁面不存在' #使404 頁面好看點 # 藍圖也可使用 全局的
    # return redirect('https://www.autohome.com.cn/beijing/adgasgsdg')
    return send_file('2.jpg')       #能夠打個廣告

代碼思惟:

af : (時間密度?糾錯) (解決不分前後,哪一個有思路?)(缺點,珍惜)

1 改爲大衆型

把頁面分開了

@app.route('/detail')
def detail():
    if session['username']:
        session['count'] += 1
        a = session['count']    #把session['count'] 賦值給a 而後傳到前端
        name = session['username']
        print(request.args.get('id'))
        return render_template('zuoye1.html', stu_dict=STUDENT_DICT, time=a,name=name)
    else:
        return redirect('/login')

@app.route('/xiangqing')
def xiangqing():
    if session['username']:
        name = session['username']
        tag = request.args.get('id')
        tag = int(tag)
        return render_template('xiangqing.html', stu_dict=STUDENT_DICT, tag=tag , name=name)
    else:
        return redirect('/login')

兩個html

zuoye.html

<table>
<td>id</td>
<td>name</td>
<td>詳情</td>

{% for id in stu_dict %}
    <tr>
        <td>{{ id }}</td>
        <td>{{ stu_dict[id].name }}</td>
        <td><a href="/xiangqing?id={{ id }}">點擊查看</a></td>
    </tr>
{% endfor %}
</table>

xiangqing.html

<table>

<td>id</td>
<td>name</td>
<td>age</td>
<td>gender</td>

{% for id in stu_dict %}
{% if tag == id %}
    <tr>
     <td>{{ id }}</td>
        <td>{{ stu_dict[id].name }}</td>
         <td>{{ stu_dict.get(id).get('age') }}</td>
         <td>{{ stu_dict.get(id).get('gender') }}</td>
      </tr>
{% endif %}
{% endfor %}
</table>

2 使用session驗證登陸狀態 思考:如何記錄登陸次數

問題1 if session['count'] is None:

KeyError: 'count' #還沒給他賦值,因此不能判斷

解決方法 : if session.get('count') is None: # get方法取值,沒有也不會報錯

先設置 session['count'] =0 當login了以後,自動就是1了(每次登錄都賦值爲0,本身沒想起來,聽的老師的提醒)

if uname == '123' and pwd == '123':
    session['username'] = uname
    #if  session['count'] is None:  #區分第一次仍是第二次登陸
     if session.get('count') is None: 
        session['count'] = 0
    return render_template('index.html',a=session['count'])

elif uname == 'a23' and pwd == 'a23':
    if session.get('count') is None: 
        session['count'] = 0
    session['username'] = uname
    return render_template('index.html',)


登陸用到session的路由函數:
if session['username']:
    session['count'] += 1
            
    name = session['username']
    return render_template('zuoye1.html', stu_dict=STUDENT_DICT,tag= tag ,time=session['count'] ,name=name)
用戶{{ name }}第{{ time }}次session登陸

有session存值,即便推出了程序也會記錄,默認31周,並且分別記錄各個用戶的登陸次數,很方便

錯誤寫法: 邏輯不對, 兩個if , 有了username就返回能夠登陸其餘的了,可是沒有,因此要去從新登陸,可是登陸沒有放行,沒有return None ,只給了有了username,可是login沒有,一直走login了 因此一直302重定向

# @app.before_request
# def be1():
#     # if session.get('username'):
#     #     return None
#     if not session.get('username'):
#           return redirect("/login")

參考了老師的寫法

@app.before_request
def be1():
  if request.path == "/login":      #給login放行
        return None
  if not session.get("username"):
        return redirect("/login")
        
            #別的默認放行 
            
或者再加上
  if session.get("username"):
        return None

錯誤3 兩我的的session值是同樣的了?

3 裝飾器
6 原理 ? : 解決方法: (1 加options)

4 user car 怎麼寫

cars.py 裏寫錯了 ,改一下
user = Blueprint('car',__name__)   -->  car = Blueprint('car',__name__)

5 floder url why
7 after 什麼意思?
8 筆記
9 css 樣式

錯誤1 app.run('0.0.0.0:9000')

正確:

app.run('0.0.0.0',9000)

錯誤2 AttributeError: 'function' object has no attribute 'name'

好像是函數def get_login():

不能寫成login 與 login的藍圖標識重名

jinja2.exceptions.TemplateNotFound: login.html

detail = Blueprint('detail',__name__,template_folder='templates',static_url_path='statics')

AttributeError: 'function' object has no attribute 'name'

def detail():       #重名了

錯誤3 ImportError: cannot import name 'STUDENT_DICT'

from zuoye import STUDENT_DICT
相關文章
相關標籤/搜索