1. 程式人生 > >Python--flask之Web框架2

Python--flask之Web框架2

一 session操作
cookie是客戶端瀏覽器的快取,而session是服務端伺服器的快取
Session 物件儲存特定使用者會話所需的屬性及配置資訊。這樣,當用戶在應用程式的 Web 頁之間跳轉時,儲存在 Session 物件中的變數將不會丟失,而是在整個使用者會話中一直存在下去。當用戶請求來自應用程式的Web 頁時,如果該使用者還沒有會話,則 Web 伺服器將自動建立一個 Session 物件。當會話過期或被放棄後,伺服器將終止該會話。Session 物件最常見的一個用法就是儲存使用者的首選項。

程式碼體驗

from flask import Flask,session
import random

app=Flask(__name__)
app.config['SECRET_KEY']=random._urandom(24)
#設定是24位的字元,每次執行伺服器的sercet_key都是不同的
#伺服器重啟會清除上一次的session資訊值

#設定session值
@app.route('/')
def index():
    #如何設定session的key-value值
    session['name']='westos'
    return 'hello world'
@app.route('/get/')
def get():
    #如何獲取
    return session.get('name')
@app.route('/delete/')
def delete():
    #如何刪除
    print(session.get('name'))
    session.pop('name')
    print(session.get('name'))
    return 'delete'
app.run(port=5001)

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
可以看到在沒執行 delete 刪除任務前,westos 是存在的,執行之後,變為 None
二 上傳檔案
如何將檔案上傳到伺服器(儲存在指定的資料夾)

import os
from flask import Flask, request, render_template
import  uuid
app = Flask(__name__)
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        # 獲取到使用者上傳的檔案物件
        f = request.files['faceImg']
        print(f.filename)
        # 獲取當前專案所在目錄位置;
        basepath = os.path.dirname(__file__)
        print(basepath)
        # 拼接路徑, 儲存檔案到static/face/xxxx
        filename = os.path.join(basepath, 'static/face', f.filename)
        # 儲存檔案
        f.save(filename)
        return  render_template('demo/upload.html', message = "上傳成功")
    else:
        return  render_template('demo/upload.html')
app.run()
import random
import functools

import psutil
from flask import Flask, request, render_template, redirect, url_for, abort,session
import os
from datetime import datetime

app=Flask(__name__)
app.config['SECRET_KEY']=random._urandom(24)
userinfo=[
    {'user':'root',
     'passwd':'westos'
     },

]

#系統監控裝飾器
def is_login(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        # run函式程式碼裡面, 如果登陸, session加入user, passwd兩個key值;
        # run函式程式碼裡面, 如果登出, session刪除user, passwd兩個key值;
        # 如果沒有登陸成功, 則跳轉到登陸介面
        if 'user' not in session:
            return redirect('/login/')
        # 如果使用者是登陸狀態, 則訪問哪個路由, 就執行哪個路由對應的檢視函式;
        return f(*args, **kwargs)

    return wrapper

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        user=request.form['user']
        passwd=request.form['passwd']
        for dbuser in userinfo:
            if user == dbuser['user'] and passwd == dbuser['passwd']:
                session['user']=user
                session['passwd']=passwd
                return redirect(url_for('index'))
        else:
            return render_template('login.html',message='使用者名稱或者密碼錯誤')
    else:
        return render_template('login.html')

@app.route('/signup/',methods=['GET','POST'])
def signup():
    if request.method == 'POST':
        user=request.form['user']
        passwd=request.form['passwd']
        for dbuser in userinfo:
            if user == dbuser['user']:
                message = '使用者已經存在'
                return render_template('signup.html',message=message)
        else:
            userinfo.append(dict(user=user,passwd=passwd))
            return redirect(url_for('login'))
    else:
        return render_template('signup.html')
@app.route('/logout/')
def logout():
    session.pop('user',None)
    session.pop('passwd',None)
    return redirect(url_for('index'))

@app.route('/sysinfo/')
@is_login
def sysinfo():
    info=os.uname()
    boot_time=psutil.boot_time()
    boot_time=datetime.fromtimestamp(boot_time)
    now_time=datetime.now()
    delta_time=now_time-boot_time
    delta_time=str(delta_time).split('.')[0]
    return render_template('sysinfo.html',
                           hostname=info.nodename,
                           sysname=info.sysname,
                           release=info.release,
                           machine=info.machine,
                           version=info.version,
                           now_time=now_time,
                           boot_time=boot_time,
                           delta_time=delta_time
                           )

@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        # 獲取到使用者上傳的檔案物件
        f = request.files['faceImg']
        print(f.filename)
        # 獲取當前專案所在目錄位置;
        basepath = os.path.dirname(__file__)
        print(basepath)
        # 拼接路徑, 儲存檔案到static/face/xxxx
        filename = os.path.join(basepath, 'static/face', f.filename)
        # 儲存檔案
        f.save(filename)
        return  render_template('upload.html', message = "上傳成功")

    else:
        return  render_template('upload.html')

@app.errorhandler(404)
def not_found(e):
    return render_template('404.html')

@app.route('/user/<int:user_id>')
def user(user_id):
    if 0<int(user_id)<=100:
        return '歡迎訪問: %s' %(user_id)
    else:
        abort(404)

app.run()

在這裡插入圖片描述
三 將使用者登陸資訊與資料庫繫結
要求將使用者登陸時的資訊,傳送至後臺與資料庫進行比對,來判斷使用者是否可登陸

imporrt pymysql
from config import  DB

# 1. 建立連線
conn  = pymysql.connect(
        host=DB.HOST,
        user = DB.USER,
        passwd = DB.PASSWD,
        port = DB.PORT,
        db = DB.DBNAME,
        )
cur = conn.cursor()

def isUserExist(username):
    """判斷使用者名稱是否存在"""
    sqli = "select * from users where name='%s'" %(username)
    res = cur.execute(sqli)
    # res返回的是sql語句查詢結果的個數;
    #  如果為0, 沒有查到。
    if res == 0:
        return  False
    else:
        return  True
        
def isPasswdOk(username, passwd):
    sqli = "select * from users where name='%s' and passwd='%s'" %(
        username, passwd)
    res = cur.execute(sqli)
    if res == 0 :
        return  False
    else:
        return  True

def addUser(username, passwd):
    """使用者註冊時, 新增資訊到資料庫中"""
    sqli = "insert into users(name, passwd) values('%s', '%s')" %(
        username, passwd)
    try:
        res = cur.execute(sqli)
        conn.commit()
    except Exception as e:
        conn.rollback()
        return e

# cur.close()
# conn.close()
if __name__ == "__main__":
    addUser('root', 'root')
    print(isUserExist('root'))
    print(isPasswdOk('root', 'root'))

config檔案:

class DB:
    HOST = '172.25.254.250'
    USER= 'root'
    PASSWD = 'westos'
    PORT = 3306
    DBNAME = 'User'

用來簡易資料庫連結這一塊

四 判斷使用者是否登陸的裝飾器
有時候一些網站的資訊,是不對外開放的,只有在登陸狀態下才是可讀的,這時候就要求對其進行限制的設定

import  functools

def is_login(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        # run函式程式碼裡面, 如果登陸, session加入user, passwd兩個key值;
        # run函式程式碼裡面, 如果登出, session刪除user, passwd兩個key值;
        # 如果沒有登陸成功, 則跳轉到登陸介面
        if 'user' not in session:
            return  redirect('/login/')
        # 如果使用者是登陸狀態, 則訪問哪個路由, 就執行哪個路由對應的檢視函式;
        return  f(*args, **kwargs)
    return  wrapper

判斷使用者是否登陸

import random
import functools

import psutil
from flask import Flask, request, render_template, redirect, url_for, abort,session
import os
from datetime import datetime

app=Flask(__name__)
app.config['SECRET_KEY']=random._urandom(24)
userinfo=[
    {'user':'root',
     'passwd':'westos'
     },

]

#系統監控裝飾器
def is_login(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        # run函式程式碼裡面, 如果登陸, session加入user, passwd兩個key值;
        # run函式程式碼裡面, 如果登出, session刪除user, passwd兩個key值;
        # 如果沒有登陸成功, 則跳轉到登陸介面
        if 'user' not in session:
            return redirect('/login/')
        # 如果使用者是登陸狀態, 則訪問哪個路由, 就執行哪個路由對應的檢視函式;
        return f(*args, **kwargs)
    return wrapper

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        user=request.form['user']
        passwd=request.form['passwd']
        for dbuser in userinfo:
            if user == dbuser['user'] and passwd == dbuser['passwd']:
                session['user']=user
                session['passwd']=passwd
                return redirect(url_for('index'))
        else:
            return render_template('login.html',message='使用者名稱或者密碼錯誤')
    else:
        return render_template('login.html')

@app.route('/signup/',methods=['GET','POST'])
def signup():
    if request.method == 'POST':
        user=request.form['user']
        passwd=request.form['passwd']
        for dbuser in userinfo:
            if user == dbuser['user']:
                message = '使用者已經存在'
                return render_template('signup.html',message=message)
        else:
            userinfo.append(dict(user=user,passwd=passwd))
            return redirect(url_for('login'))
    else:
        return render_template('signup.html')
@app.route('/logout/')
def logout():
    session.pop('user',None)
    session.pop('passwd',None)
    return redirect(url_for('index'))

@app.route('/sysinfo/')
@is_login
def sysinfo():
    info=os.uname()
    boot_time=psutil.boot_time()
    boot_time=datetime.fromtimestamp(boot_time)
    now_time=datetime.now()
    delta_time=now_time-boot_time
    delta_time=str(delta_time).split('.')[0]
    return render_template('sysinfo.html',
                           hostname=info.nodename,
                           sysname=info.sysname,
                           release=info.release,
                           machine=info.machine,
                           version=info.version,
                           now_time=now_time,
                           boot_time=boot_time,
                           delta_time=delta_time
                           )


@app.errorhandler(404)
def not_found(e):
    return render_template('404.html')

@app.route('/user/<int:user_id>')
def user(user_id):
    if 0<int(user_id)<=100:
        return '歡迎訪問: %s' %(user_id)
    else:
        abort(404)
app.run()

在這裡插入圖片描述
檢視系統資訊時,調轉到登陸頁面,登陸後,放了檢視
在這裡插入圖片描述

五 表單處理

主函式:

import random
from flask import Flask, redirect, render_template
from forms import LoginForm
from flask_bootstrap import  Bootstrap

app = Flask(__name__)
bootstrap = Bootstrap(app)
app.config['SECRET_KEY'] =  random._urandom(24)

@app.route('/success/')
def success():
    return  "success"

@app.route('/login/', methods=('GET', 'POST'))
def submit():
    # 例項化表單物件;
    form = LoginForm()
    if form.validate_on_submit():
        print(form.data)
        return redirect('/success/')
    return render_template('demo/login.html', form=form)
app.run()

forms.py檔案:用來設定規則

from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField
from wtforms.validators import DataRequired, Length

class LoginForm(FlaskForm):
    name=StringField(
        label='使用者名稱/郵箱/密碼',
        validators=[
            DataRequired('請輸入使用者名稱'),
            Length(3,20)
        ]
    )
    passwd = PasswordField(
        label='密碼',
        validators=[
            DataRequired('請輸入密碼'),
            Length(3,20)
        ]
    )

html頁面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="post" action="/">
    {{form.hidden_tag()}}
    {{form.name.label}}{{form.name}}
    {{form.passwd.label}}{{form.passwd}}
    <input type="submit" value="Go">
</form>
</body>
</html>

在這裡插入圖片描述