一個web應(yīng)用的誕生(5)--數(shù)據(jù)表單

下面把角色分為兩種桐臊,普通用戶和管理員用戶轴合,至少對于普通用戶來說,直接修改DB是不可取的平酿,要有用戶注冊的功能讯檐,下面就開始進(jìn)行用戶注冊的開發(fā)。

用戶表

首先要想好用戶注冊的時候需要提供什么信息:用戶名染服、密碼、昵稱叨恨、郵箱柳刮、生日、性別痒钝、自我介紹秉颗,下面就按照這些信息修改用戶模型:

class User(db.Model):
    __tablename__="users"
    id=db.Column(db.Integer,primary_key=True)
    username=db.Column(db.String(50),unique=True,index=True)
    password=db.Column(db.String(50))
    nickname=db.Column(db.String(50))
    email=db.Column(db.String(100))
    birthday=db.Column(db.DateTime)
    gender=db.Column(db.Integer)
    remark=db.Column(db.String(200))
    role_id=db.Column(db.Integer,db.ForeignKey("roles.id"))

然后使用腳本修改db

python default.py db migrate -m "修改用戶表"

回車后界面顯示內(nèi)容為:

然后進(jìn)行db差異的改動
python default.py db upgrade
這時看db中的表結(jié)構(gòu):

已經(jīng)修改成功

注冊界面

然后新建register.html模板栅隐,設(shè)置登錄表單:

{% extends "base.html"%}
{% block content %} <!--具體內(nèi)容-->
<div class="container">
    <div class="row"></div>
    <div class="row">

        <div>
            <div class="page-header">
                <h1>歡迎您注冊</h1>
            </div>
            {% for message in get_flashed_messages() %}
            <div class="alert alert-warning">
              <button type="button" class="close" data-dismiss="alter">&times</button>
              {{message}}
            </div>
            {% endfor %}
            <form method="post">
              <div class="form-group">
                <label for="username">用戶名</label>
                <input type="text" class="form-control" name="username" id="username" placeholder="請輸入用戶名">
              </div>
              <div class="form-group">
                <label for="passworld">密碼</label>
                <input type="password" class="form-control" name="password" id="passworld" placeholder="請輸入密碼">
              </div>
              <div class="form-group">
                <label for="email">昵稱</label>
                <input type="email" class="form-control" name="nickname" id="nickname" placeholder="請輸入昵稱">
              </div>
              <div class="form-group">
                <label for="birthday">生日</label>
                <input type="date" class="form-control" name="birthday" id="birthday" placeholder="請輸入生日">
              </div>
              <div class="form-group">
                <label >性別</label>
                <label  class="form-control">
                    <input type="radio" name="gender" value="0" id="gender0"><label for="gender0">男</label>
                    <input type="radio" name="gender" value="1" id="gender1"><label for="gender1">女</label>
                </label>
              </div>
              <div class="form-group">
                <label for="email">電子郵箱</label>
                <input type="email" class="form-control" name="email" id="email" placeholder="請輸入電子郵箱">
              </div>
              <button type="submit" class="btn btn-default">登錄</button>
            </form>
        </div>
    </div>
</div>
{% endblock %}

然后在default.py文件中新增register路由蝎亚,代碼為:

@app.route("/register",methods=["GET"])
def register():
    return  render_template("/register.html")

運行界面正常,然后增加post路由:

@app.route("/register",methods=["Post"])
def registerPost():
    user=User();
    user.username=request.form.get("username","")
    user.password = request.form.get("password", "")
    user.birthday = request.form.get("birthday", "")
    user.email = request.form.get("email", "")
    user.gender = request.form.get("gender", "")
    user.nickname = request.form.get("nickname", "")
    user.role_id = 1 #暫時約定公開用戶角色為1

    #判斷,其中用戶名,密碼,昵稱不能為空
    if(len(user.username.strip())==0):
        flash("用戶名不能為空")
        return render_template("/register.html")
    if(len(user.password.strip())==0):
        flash("用戶密碼不能為空")
        return render_template("/register.html")
    if (len(user.nickname.strip()) == 0):
        flash("用戶昵稱不能為空")
        return render_template("/register.html")
    db.session.add(user);
    flash("您已注冊成功")
    return render_template("/register.html")

代碼有點啰嗦炕舵,不漂亮栋荸,但基本意圖能表達(dá)清楚菇怀,功能也可以實現(xiàn),但現(xiàn)在的問題來了晌块,加入我新增一個字段爱沟,那么需要修改三處代碼(html,form.get,校驗)匆背,并且尤其是需要修改html呼伸,而且html部分沒有驗證,如果增加客戶端驗證的話钝尸,需要修改的會更多括享。那么有沒有一個針對表單進(jìn)行優(yōu)化的工具呢,答案是當(dāng)然有珍促,輪到wtf登場了铃辖。

引入WTF表單框架

和之前一樣,首先需要安裝插件踢星。

pip3.6 install flask-wtf

然后引入所需的包

from flask.ext.wtf import Form
from wtforms import StringField,PasswordField,SubmitField,RadioField
from wtforms.validators import DataRequired,EqualTo,Length

下面創(chuàng)建一個表單RegisterForm:

class RegisterForm(Form):
    username = StringField("請輸入用戶名", validators=[DataRequired()])
    password = PasswordField("請輸入密碼", validators=[DataRequired()])
    repassword=PasswordField("確認(rèn)密碼", validators=[EqualTo("password")])
    nickname= StringField("昵稱")
    birthday= DateField("出生日期")
    email= StringField("郵箱地址", validators=[Email()])
    gender= RadioField("性別", choices=[("0", "男"), ("1", "女")], default=0)
    remark= TextAreaField("自我簡介")
    submit=SubmitField("提交")

修改register.html模板:

{% extends "base.html"%}
{% block content %} <!--具體內(nèi)容-->
{% import "bootstrap/wtf.html" as wtf %}  <!--導(dǎo)入bootstrap模板 -->
<div class="container">
    <div class="row"></div>
    <div class="row">

        <div>
            <div class="page-header">
                <h1>歡迎您注冊</h1>
            </div>
            {% for message in get_flashed_messages() %}
            <div class="alert alert-warning">
              <button type="button" class="close" data-dismiss="alter">&times</button>
              {{message}}
            </div>
            {% endfor %}
            {{ wtf.quick_form(form)}} <!--創(chuàng)建表單-->
        </div>
    </div>
</div>
{% endblock %}

執(zhí)行澳叉,輸出結(jié)果:

阿歐隙咸,報錯了,看看輸出是什么錯誤:

注意紅線一句成洗,是CSRF錯誤五督,CSRF的概念可直接百度,知道問題了,其實也很好修改瓶殃,在框架中增加一個秘鑰就可以有效的防范了充包,在default.py中增加一行:

app.config['SECRET_KEY'] = "Niu_blog String"

秘鑰字符串可自定義

然后再次運行,出現(xiàn)界面:

并且包含驗證bootstrap的驗證樣式遥椿,接下來繼續(xù)改造default.py已完成此注冊功能

@app.route("/register",methods=["GET","POST"])
def register():
    form=RegisterForm()
    if form.validate_on_submit():
        user=User()
        user.username=form.username.data
        user.password=form.password.data
        user.birthday=form.birthday.data
        user.email=form.email.data
        user.gender=form.gender.data
        user.nickname=form.nickname.data
        user.role_id=1          #暫時約定公開用戶角色為1
        db.session.add(user)
    return  render_template("/register.html",form=form)

注意此時已刪除registerPost方法

好運行測試一下

點擊提交:

阿歐基矮,日期格式為啥不對?這個要從源碼里看了:

class DateField(DateTimeField):
    """
    Same as DateTimeField, except stores a `datetime.date`.
    """
    def __init__(self, label=None, validators=None, format='%Y-%m-%d', **kwargs):
        super(DateField, self).__init__(label, validators, format, **kwargs)

    def process_formdata(self, valuelist):
        if valuelist:
            date_str = ' '.join(valuelist)
            try:
                self.data = datetime.datetime.strptime(date_str, self.format).date()
            except ValueError:
                self.data = None
                raise ValueError(self.gettext('Not a valid date value'))

這個是wtforms的field的源碼冠场,位于/wtforms/fields/core.py的745行家浇,可以看到,這里支持的日期格式為年-月-日格式碴裙,格式限定比較死钢悲,并且文本框沒有用html5的date而是普通的text,解決辦法以后再說舔株,暫時先修改輸入莺琳,改為1988-2-5,然后點擊提交:

注意载慈,由于代碼中提交成功之后依然是返回到此頁惭等,并注入內(nèi)容,所以顯示沒有問題办铡,看看db中:

記錄正常進(jìn)入db辞做,功能實現(xiàn)完成。

改善登錄頁

下面改造登錄頁寡具,首先創(chuàng)建登錄表單:

class LoginForm(Form):
    username=StringField("請輸入用戶名",validators=[DataRequired()])
    password=PasswordField("請輸入密碼")
    submit=SubmitField("登錄")

修改登錄模板頁:

{% extends "base.html"%}
{% import "bootstrap/wtf.html" as wtf %}
{% block content %} <!--具體內(nèi)容-->
<div class="container">
    <div class="row"></div>
    <div class="row">

        <div class="col-md-4 col-md-offset-4 col-sm-6 col-sm-offset-3">
            <div class="page-header">
                <h1>歡迎您登陸</h1>
            </div>
            {% for message in get_flashed_messages() %}
            <div class="alert alert-warning">
              <button type="button" class="close" data-dismiss="alter">&times</button>
              {{message}}
            </div>
            {% endfor %}
            {{ wtf.quick_form(form)}}
        </div>
    </div>
</div>
{% endblock %}

修改路由方法:

@app.route("/login",methods=["GET","POST"])
def login():
    form=LoginForm()
    if form.validate_on_submit():
        username = form.username.data
        password = form.password.data
        user = User.query.filter_by(username=username, password=password).first()
        if user is not None:
            session["user"] = username
            return render_template("/index.html", name=username, site_name='myblog')
        else:
            flash("您輸入的用戶名或密碼錯誤")
            return render_template("/login.html",form=form)  # 返回的仍為登錄頁
    return render_template("/login.html",form=form)

重啟服務(wù)凭豪,運行程序,輸入zhangji和123后晒杈,成功登錄首頁

回到首頁

現(xiàn)在首頁白茫茫的一片嫂伞,什么內(nèi)容都沒有,正常的輕博客應(yīng)該登錄后顯示發(fā)博按鈕拯钻,已關(guān)注文章等帖努,但首先要記錄登錄的狀態(tài),這些將在下一章說明粪般。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拼余,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子亩歹,更是在濱河造成了極大的恐慌匙监,老刑警劉巖凡橱,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異亭姥,居然都是意外死亡稼钩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門达罗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坝撑,“玉大人,你說我怎么就攤上這事粮揉⊙怖睿” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵扶认,是天一觀的道長侨拦。 經(jīng)常有香客問我,道長辐宾,這世上最難降的妖魔是什么阳谍? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮螃概,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鸽疾。我一直安慰自己吊洼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布制肮。 她就那樣靜靜地躺著冒窍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪豺鼻。 梳的紋絲不亂的頭發(fā)上综液,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機與錄音儒飒,去河邊找鬼谬莹。 笑死,一個胖子當(dāng)著我的面吹牛桩了,可吹牛的內(nèi)容都是我干的附帽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼井誉,長吁一口氣:“原來是場噩夢啊……” “哼蕉扮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起颗圣,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤喳钟,失蹤者是張志新(化名)和其女友劉穎屁使,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奔则,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蛮寂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了应狱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片共郭。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖疾呻,靈堂內(nèi)的尸體忽然破棺而出除嘹,到底是詐尸還是另有隱情,我是刑警寧澤岸蜗,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布尉咕,位于F島的核電站,受9級特大地震影響璃岳,放射性物質(zhì)發(fā)生泄漏年缎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一铃慷、第九天 我趴在偏房一處隱蔽的房頂上張望单芜。 院中可真熱鬧,春花似錦犁柜、人聲如沸洲鸠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扒腕。三九已至,卻和暖如春萤悴,著一層夾襖步出監(jiān)牢的瞬間瘾腰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工覆履, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蹋盆,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓硝全,卻偏偏與公主長得像怪嫌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子柳沙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 22年12月更新:個人網(wǎng)站關(guān)停岩灭,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,169評論 22 257
  • 4 創(chuàng)建一個社交網(wǎng)站 在上一章中,你學(xué)習(xí)了如何創(chuàng)建站點地圖和訂閱赂鲤,并且為博客應(yīng)用構(gòu)建了一個搜索引擎噪径。在這一章中柱恤,你...
    lakerszhy閱讀 2,168評論 0 7
  • 此段內(nèi)容簡要來自自強學(xué)堂的教程詳情請查詢自強學(xué)堂 一、 后臺的運作流程 接收request請求 處理數(shù)據(jù) 獲取請求...
    coder_ben閱讀 5,246評論 6 56
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理找爱,服務(wù)發(fā)現(xiàn)梗顺,斷路器,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • 上一章實現(xiàn)了登錄的部分功能车摄,之所以說是部分功能寺谤,是因為用戶名和密碼寫成固定值肯定是不可以的,一個整體的功能吮播,至少需...
    雙魚座的牛閱讀 302評論 0 2