目錄html
from flask import Flask, render_template, url_for, views app = Flask(__name__) class Login(views.MethodView): def get(self, *args, **kwargs): print(url_for('my_login')) # 經過my_login進行反向解析 return render_template('login.html') def post(self, *args, **kwargs): return 'login success' app.add_url_rule('/login', view_func=Login.as_view('my_login')) if __name__ == '__main__': app.run(debug=True)
注意: 視圖類中定義了哪些方法, 就能夠容許哪一種方式的請求, 也能夠經過指定參數methods=["GET","POST"]
, 指定參數時能夠在視圖類中指定, 也能夠在add_url_rule
方法中指定.python
咱們使用過flask內置的session,知道它是把session存放在瀏覽器,即客戶端。今天要學習的flask-session是flask的第三方組件,看一下它和flask內置的session有什麼不一樣以及它的使用方法。redis
flask-session是flask框架的session組件,flask內置session使用簽名cookie保存,而該組件則將支持session保存到多個地方,如:sql
- redis - memcached - filesystem - mongodb - sqlalchmey
pip3 install flask-session
from flask import Flask, session app = Flask(__name__) app.secret_key = '~!@#$%' # 配置session反向解析的祕鑰 @app.route('/index') def index(): session['user'] = 'value' return 'hello' if __name__ == '__main__': app.run(debug=True)
啓動該程序, 使用瀏覽器訪問http://127.0.0.1:5000
, 可看到以下session:mongodb
from flask import Flask, session from flask_session import Session # 導入flask-session中的Session類 from redis import Redis app = Flask(__name__) # 對實例進行配置 app.config['SESSION_TYPE'] = 'redis' app.config['SESSION_REDIS'] = Redis(host='127.0.0.1', port=6379, db=6) Session(app) # 把原來app中的session進行替換 @app.route('/index') def index(): session['user'] = 'value' return 'hello' if __name__ == '__main__': app.run(debug=True)
啓動程序, 瀏覽器訪問http://127.0.0.1:5000
, 找到瀏覽器Cookie中的鍵值對:django
使用cmd控制檯打開redis客戶端, 進行以下操做:flask
WTForms是flask的組件, 相似於django的modelform組件.瀏覽器
pip3 install wtforms
wtf.py
文件:cookie
from flask import Flask, render_template, request from wtforms.fields import simple, core from wtforms import Form, validators app = Flask(__name__, template_folder="./app01/templates") # Form組件: 註冊類 class RegForm(Form): username = simple.StringField( label='用戶名', validators=[ validators.DataRequired(message='該字段不能爲空'), validators.Length(min=3, max=10, message='用戶名必須3-10個字符') ], id='user_id', render_kw={'class': 'user_name'} ) password = simple.PasswordField( label='密碼', validators=[ validators.DataRequired(message='該字段不能爲空'), validators.Length(min=6, max=12, message='密碼必須6-12個字符') ], id='pwd', render_kw={'class': 'pwd'} ) repassword = simple.PasswordField( label='確認密碼', validators=[ validators.EqualTo(fieldname='password', message='兩次密碼不一致'), ], id='re_pwd', render_kw={'class': 're_pwd'} ) email = simple.StringField( label='郵箱', validators=[ validators.DataRequired(message='該字段不能爲空'), validators.Email(message='必須符合郵箱格式') ], id='email', render_kw={'class': 'email'} ) gender = core.RadioField( label='性別', coerce=int, # 提交的數據類型,即1或2的數據類型(以下所示) choices=( (1, '女'), # 元組第一個元素是value, 第二個元素是顯示的值 (2, '男') ), default=1 # 默認值爲1 ) hobby = core.SelectMultipleField( label='愛好', validators=[ validators.Length(min=1, max=3, message='愛好的數量爲1-3個'), ], coerce=str, # 注意,類型爲str時,下面choices中每一個元組第一個值必須帶引號 choices=( ('1', '健身'), ('2', '游泳'), ('3', '旅遊'), ('4', '攝影'), ), default=('1', '3') # 默認選中兩個 ) # button = simple.SubmitField # 渲染提交按鈕 # Form組件: 登陸類 class LoginForm(Form): username = simple.StringField( label='用戶名', validators=[ # 校驗條件,可迭代條件,由於可能校驗多個條件 validators.DataRequired(message='該字段不能爲空'), validators.Length(min=3, max=10, message='用戶名必須3-10個字符') ], description='this is a description', # 描述標記 id='user_id', # 標籤id widget=None, # 默認組件(好比input type='text')在StringField中已經被實例化了 render_kw={'class': 'my_login'} # 添加屬性和值 ) password = simple.PasswordField( label='密碼', validators=[ validators.DataRequired(message='該字段不能爲空'), validators.Length(min=6, max=12, message='密碼必須6-12個字符') ], description='this is a description', id='pwd', default=None, render_kw={'class': 'pwd'} ) # 視圖函數: 註冊 @app.route('/reg', methods=['GET', 'POST']) def reg(): if request.method == 'GET': rf = RegForm() # 實例化Form組件 return render_template('register.html', wtf=rf) else: rf = RegForm(request.form) if rf.validate(): # 校驗成功 return rf.data.get('username') else: # 校驗失敗 print(rf.data) print(rf.errors) return render_template('register.html', wtf=rf) # 視圖函數: 登陸 @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'GET': lf = LoginForm() # 實例化Form組件 return render_template('login.html', wtf=lf) else: lf = LoginForm(request.form) # 將用戶提交的數據傳入組件中 if lf.validate(): # 校驗用戶提交的數據 return lf.data.get('username') # 正確的數據在lf.data中 else: # 校驗失敗,錯誤的數據在lf.errors中 return render_template('login.html', wtf=lf) if __name__ == '__main__': app.run(debug=True)
register.html
文件:session
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊</title> </head> <body> <form action="" method="post" novalidate> {% for field in wtf %} <p> {{ field.label }} {{ field }} {{ field.errors.0 }} </p> {% endfor %} <input type="submit" value="註冊"> </form> </body> </html>
login.html
文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登陸</title> </head> <body> <form action="" method="post" novalidate> <p> {{ wtf.username.label }} {{ wtf.username }}{{ wtf.username.errors.0 }} </p> <p> {{ wtf.password.label }} {{ wtf.password }}{{ wtf.password.errors.0 }} </p> <input type="submit" value="登陸"> </form> </body> </html>