一個(gè)基于flask的web應(yīng)用誕生 用戶注冊功能開發(fā)(5)
下面把角色分為兩種,普通用戶和管理員用戶,至少對(duì)于普通用戶來說,直接修改DB是不可取的,要有用戶注冊的功能,下面就開始進(jìn)行用戶注冊的開發(fā)。
用戶表
首先要想好用戶注冊的時(shí)候需要提供什么信息:用戶名、密碼、昵稱、郵箱、生日、性別、自我介紹,下面就按照這些信息修改用戶模型:
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差異的改動(dòng)
python default.py db upgrade
這時(shí)看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">×</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")
運(yùn)行界面正常,然后增加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 #暫時(shí)約定公開用戶角色為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")
代碼有點(diǎn)啰嗦,不漂亮,但基本意圖能表達(dá)清楚,功能也可以實(shí)現(xiàn),但現(xiàn)在的問題來了,加入我新增一個(gè)字段,那么需要修改三處代碼(html,form.get,校驗(yàn)),并且尤其是需要修改html,而且html部分沒有驗(yàn)證,如果增加客戶端驗(yàn)證的話,需要修改的會(huì)更多。那么有沒有一個(gè)針對(duì)表單進(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)建一個(gè)表單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">×</button> {{message}} </div> {% endfor %} {{ wtf.quick_form(form)}} <!--創(chuàng)建表單--> </div> </div> </div> {% endblock %}
執(zhí)行,輸出結(jié)果:
阿歐,報(bào)錯(cuò)了,看看輸出是什么錯(cuò)誤:
注意紅線一句,是CSRF錯(cuò)誤,CSRF的概念可直接百度,知道問題了,其實(shí)也很好修改,在框架中增加一個(gè)秘鑰就可以有效的防范了,在default.py中增加一行:
app.config['SECRET_KEY'] = "Niu_blog String"
秘鑰字符串可自定義
然后再次運(yùn)行,出現(xiàn)界面:
并且包含驗(yàn)證bootstrap的驗(yàn)證樣式,接下來繼續(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 #暫時(shí)約定公開用戶角色為1 db.session.add(user) return render_template("/register.html",form=form)
注意此時(shí)已刪除registerPost方法
好運(yùn)行測試一下
點(diǎn)擊提交:
阿歐,日期格式為啥不對(duì)?這個(gè)要從源碼里看了:
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'))
這個(gè)是wtforms的field的源碼,位于/wtforms/fields/core.py的745行,可以看到,這里支持的日期格式為年-月-日格式,格式限定比較死,并且文本框沒有用html5的date而是普通的text,解決辦法以后再說,暫時(shí)先修改輸入,改為1988-2-5,然后點(diǎn)擊提交:
注意,由于代碼中提交成功之后依然是返回到此頁,并注入內(nèi)容,所以顯示沒有問題,看看db中:
記錄正常進(jìn)入db,功能實(shí)現(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">×</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("您輸入的用戶名或密碼錯(cuò)誤") return render_template("/login.html",form=form) # 返回的仍為登錄頁 return render_template("/login.html",form=form)
重啟服務(wù),運(yùn)行程序,輸入zhangji和123后,成功登錄首頁
回到首頁
現(xiàn)在首頁白茫茫的一片,什么內(nèi)容都沒有,正常的輕博客應(yīng)該登錄后顯示發(fā)博按鈕,已關(guān)注文章等,但首先要記錄登錄的狀態(tài),這些將在下一章說明。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python中isoweekday和weekday的區(qū)別及說明
這篇文章主要介紹了python中isoweekday和weekday的區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07如何利用opencv訓(xùn)練自己的模型實(shí)現(xiàn)特定物體的識(shí)別
在Python中通過OpenCV自己訓(xùn)練分類器進(jìn)行特定物體實(shí)時(shí)識(shí)別,下面這篇文章主要給大家介紹了關(guān)于如何利用opencv訓(xùn)練自己的模型實(shí)現(xiàn)特定物體的識(shí)別,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10Python lambda和Python def區(qū)別分析
Python支持一種有趣的語法,它允許你快速定義單行的最小函數(shù)。這些叫做lambda的函數(shù),是從Lisp借用來的,可以用在任何需要函數(shù)的地方2014-11-11Python周期任務(wù)神器之Schedule模塊使用詳解
這篇文章主要為大家詳細(xì)介紹了Python中的周期任務(wù)神器—Schedule模塊的安裝和初級(jí)、進(jìn)階使用方法,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-04-04Python將主機(jī)名轉(zhuǎn)換為IP地址的方法
今天小編就為大家分享一篇Python將主機(jī)名轉(zhuǎn)換為IP地址的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08