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 ....
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
參數:前端
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:
print(page,page1,page2) #傳參 (必須是定長的傳三個)
route('details/int:
route('details/string:
#經過路由地址訪問文件
/s1.py url地址
def detail(folder,filename) #folder 跨目錄
#寫url /template/xx.html(前面是。。/後面對應)
fp=os.path.join(folder,filename)
return send_file()
初始化配置
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 能夠阻攔域名 子域名(替代分發)上兩個
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'
不要把時間浪費在路上 ----哪一個名人
當成是 一個不能被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多個藍圖
@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.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 : (時間密度?糾錯) (解決不分前後,哪一個有思路?)(缺點,珍惜)
把頁面分開了
@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>
KeyError: 'count' #還沒給他賦值,因此不能判斷
先設置 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 裝飾器
6 原理 ? : 解決方法: (1 加options)
cars.py 裏寫錯了 ,改一下 user = Blueprint('car',__name__) --> car = Blueprint('car',__name__)
5 floder url why
7 after 什麼意思?
8 筆記
9 css 樣式
正確:
app.run('0.0.0.0',9000)
好像是函數def get_login():
不能寫成login 與 login的藍圖標識重名
detail = Blueprint('detail',__name__,template_folder='templates',static_url_path='statics')
AttributeError: 'function' object has no attribute 'name'
def detail(): #重名了
from zuoye import STUDENT_DICT