Python Web框架 Flask - Flask表單法精、項目結構多律、文件上傳、發(fā)送郵件

Flask表單

Flask項目開發(fā)中針對提交表單的校驗搂蜓,可以使用Flask-WTF擴展庫進行快速的字段校驗

安裝Flask-WTF

pip install flask-wtf

定義form.py文件進行表單驗證

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired, EqualTo


class UserRegisterForm(FlaskForm):
    username = StringField('用戶名', validators=[DataRequired()])
    password = StringField('密碼', validators=[DataRequired()])
    password2 = StringField('確認密碼', validators=[DataRequired(), EqualTo('password', '密碼不一致')])
    submit = SubmitField('提交')

定義注冊視圖函數

當HTTP請求為GET時狼荞,將表單驗證對象返回給頁面。

當HTTP請求為POST時帮碰,通過方法validate_on_submit()方法進行字段校驗和提交判斷相味,如果校驗失敗,則可以從form.errors中獲取錯誤信息殉挽。

如果驗證通過丰涉,則從form.字段.data中獲取到字段的值。

@blue.route('/register/', methods=['GET', 'POST'])
def register():
    form = UserRegisterForm()
    if request.method == 'GET':
        return render_template('register.html', form=form)

    if request.method == 'POST':
        if form.validate_on_submit():
            username = form.username.data
            password = form.password.data
            # 保存
            user = User()
            user.username = username
            password = generate_password_hash(password)
            user.password = password
            user.save()
            return '創(chuàng)建成功'

        else:
            return render_template('register.html', form=form)

使用表單后斯碌,會在模板中自動生成表單標簽
在括號中可以自定義屬性一死,包括type、style等

    <h2>注冊</h2>
    <form action="" method="post">
        {{ form.csrf_token }}
        {{ form.username.label }} : {{ form.username }} <br>
        {{ form.password.label }} : {{ form.password(type='password') }} <br>
        {{ form.password2.label }} : {{ form.password2(type='password') }} <br>
        {{ form.submit }}
    </form>

Flask文件上傳

模板定義

form表單中定義上傳文件的字段输拇,定義type='file'摘符。注意上傳的表單中一定要添加enctype="multipart/form-data"參數。

    <form action="" method="post" enctype="multipart/form-data">
        圖片: <input type="file" name="icon"><br>
        <input type="submit" value="提交">
    </form>

圖片保存

圖片的保存可以直接通過request.files獲取模板中上傳的圖片策吠,并調用save()方法進行保存逛裤。

@blue.route('/icon/', methods=['GET', 'POST'])
def icon():
    if request.method == 'GET':
        return render_template('icon.html')

    if request.method == 'POST':
        # 1.獲取圖片
        icon = request.files.get('icon')
        # 2.保存圖片
        # path: E:/workspace/flask/day05/static/media/xxx.jpg
        path = os.path.join(MEDIA_PATH, icon.filename)
        icon.save(path)

        # 3.修改字段
        user = User.query.filter(User.username == 'aaa').first()
        user.icon = icon.filename
        user.save()
        return redirect(url_for('user.index'))

圖片渲染

案例的場景是修改當前登錄系統(tǒng)用戶的icons字段,在模板中可以通過current_user參數獲取當前登錄系統(tǒng)的用戶對象猴抹,并訪問icons屬性即可獲取到存儲在數據庫中的圖片路徑带族。

    <img src="/static/media/{{ user.icon }}" style="width: 500px">

項目結構

manage.py - 項目啟動

from flask_script import Manager
from utils.app import create_app

# 獲取flask對象app
app = create_app()
# 管理app
manage = Manager(app)

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

app.py - 初始化項目,加載配置蟀给,藍圖注冊

from flask import Flask

from utils.config import Conf
from app.views import blue
from app.models import db
from utils.settings import STATIC_PATH, TEMPLATE_PATH


def create_app():

    app = Flask(__name__,
                static_folder=STATIC_PATH,
                template_folder=TEMPLATE_PATH)
    # 加載配置
    app.config.from_object(Conf)
    # 藍圖
    app.register_blueprint(blueprint=blue, url_prefix='/user')
    # 初始化
    db.init_app(app)

    return app

config - 配置信息(鍵值對形式)

from utils.functions import get_sqlalchemy_uri
from utils.settings import DATABASE


class Conf():
    SQLALCHEMY_DATABASE_URI = get_sqlalchemy_uri(DATABASE)
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    PRESERVE_CONTEXT_ON_EXCEPTION = False
    SECRET_KEY = 'qwertyuiopasdfghjklzxcvbnm1234567890'

settings.py - 經常修改的詳細配置信息 - static蝙砌、templates、media等路徑的配置


import os

# 基礎路徑
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# static路徑
STATIC_PATH = os.path.join(BASE_DIR, 'static')
# templates路徑
TEMPLATE_PATH = os.path.join(BASE_DIR, 'templates')
# media路徑
MEDIA_PATH = os.path.join(STATIC_PATH, 'media')


DATABASE = {
    'NAME': 'flask',
    'USER': 'root',
    'PASSWORD': '123456',
    'HOST': '127.0.0.1',
    'PORT': '3306',
    'ENGINE': 'mysql',
    'DRIVER': 'pymysql'
}

在functions.py文件中獲得mysql連接

def get_sqlalchemy_uri(DATABASE):
    # mysql+pymysql://root:123456@127.0.0.1:3306/flask
    user = DATABASE['USER']
    password = DATABASE['PASSWORD']
    host = DATABASE['HOST']
    port = DATABASE['PORT']
    name = DATABASE['NAME']
    engine = DATABASE['ENGINE']
    driver = DATABASE['DRIVER']

    return f'{engine}+{driver}://{user}:{password}@{host}:{port}/{name}'

自定義狀態(tài)碼清單

USER_LOGIN_PARAMS_IS_INVALID = {'code': 10001, 'msg': '請?zhí)顚懲暾畔?}
USER_LOGIN_USERNAME_OR_PASSWORD_ERROR = {'code': 10002, 'msg': '用戶名或者密碼錯誤'}
SUCCESS = {'code': 200, 'msg': '請求成功'}

Flask郵件發(fā)送

from flask import Flask

from flask_mail import Mail, Message


app = Flask(__name__)

app.config['MAIL_SERVER'] = 'smtp.163.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'ypcc624@163.com'
app.config['MAIL_PASSWORD'] = 'abcd1234'

mail = Mail(app)


@app.route('/send_mail/')
def send_mail():
    message = Message('郵件轟炸機', sender=app.config["MAIL_USERNAME"], recipients=["779598160@qq.com"])
    message.body = '成功啦跋理,開始轟炸啦'

    send_email(message)

    return '發(fā)送成功'


def send_email(msg):
    mail.send(msg)


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

參數以及說明

首先需要開啟客戶端授權碼择克,并設置授權碼。

安裝flask-mail

pip install flask-mail

設置的參數定義如下:
MAIL_SERVER: 電子郵件服務器的主機名或IP地址前普, 默認為localhost

MAIL_PORT: 電子郵件服務器的端口肚邢,默認為25

MAIL_USE_TLS: 啟用傳輸層安全協(xié)議,默認為False

MAIL_USE_SSL: 啟用安全套接層協(xié)議, 默認為False

MAIL_USERNAME: 郵件賬戶的用戶名

MAIL_PASSWORD:郵件賬戶的密碼骡湖,為在163中設置的授權碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末贱纠,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子响蕴,更是在濱河造成了極大的恐慌谆焊,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浦夷,死亡現場離奇詭異辖试,居然都是意外死亡,警方通過查閱死者的電腦和手機军拟,發(fā)現死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門剃执,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人懈息,你說我怎么就攤上這事肾档。” “怎么了辫继?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵怒见,是天一觀的道長。 經常有香客問我姑宽,道長遣耍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任炮车,我火速辦了婚禮舵变,結果婚禮上,老公的妹妹穿的比我還像新娘瘦穆。我一直安慰自己纪隙,他們只是感情好,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布扛或。 她就那樣靜靜地躺著绵咱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪熙兔。 梳的紋絲不亂的頭發(fā)上悲伶,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天,我揣著相機與錄音住涉,去河邊找鬼麸锉。 笑死,一個胖子當著我的面吹牛舆声,可吹牛的內容都是我干的淮椰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼主穗!你這毒婦竟也來了?” 一聲冷哼從身側響起毙芜,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤忽媒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后腋粥,有當地人在樹林里發(fā)現了一具尸體晦雨,經...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年隘冲,在試婚紗的時候發(fā)現自己被綠了闹瞧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡展辞,死狀恐怖奥邮,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情罗珍,我是刑警寧澤洽腺,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站覆旱,受9級特大地震影響蘸朋,放射性物質發(fā)生泄漏。R本人自食惡果不足惜扣唱,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一藕坯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧噪沙,春花似錦炼彪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至朋腋,卻和暖如春齐疙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背旭咽。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工贞奋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人穷绵。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓轿塔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子勾缭,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內容

  • 22年12月更新:個人網站關停揍障,如果仍舊對舊教程有興趣參考 Github 的markdown內容[https://...
    tangyefei閱讀 35,184評論 22 257
  • 在上一個章節(jié),我們已經創(chuàng)建了一個基礎的Blog程序×┯桑現在我們將使用一些Dajngo高級功能毒嫡,去實現一個完整的blo...
    金金剛狼閱讀 3,586評論 1 12
  • 最近看了Flask Web開發(fā):基于Python的Web應用開發(fā)實戰(zhàn),書中詳細介紹了Web程序的開發(fā)幻梯、測試兜畸、部署過...
    SheHuan閱讀 8,791評論 2 33
  • 我那時簡單粗暴的可怕,感情的得失竟然只會用金錢碘梢,路程咬摇,時間來衡量,我懼怕一切沒有刻度的東西煞躬,沒有刻度肛鹏,不能...
    七虞閱讀 273評論 0 1
  • 你那里下雪了嗎龄坪,我在這兒想念你吶; 你在遠方還好嗎复唤,我在這兒祝福你呀健田; 你在為她歌唱吧,我聽見了你的心聲胺鹑摇妓局; 你在...
    Dolphin小妮子閱讀 369評論 3 6