flask form表單驗證


 

新建forms.py文件

#!/usr/bin/env python
#-*-coding:utf-8-*-

#導入模塊
from flask_wtf import FlaskForm                 #FlaskForm 為表單基類 from wtforms import StringField,PasswordField,SubmitField     #導入字符串字段,密碼字段,提交字段 from wtforms.validators import DataRequired,ValidationError
from models import Admin              #從models導入模型(表)

#定義登錄表單,並且需要在視圖函數(views.py)中實例化
class LoginForm(FlaskForm): account = StringField( # 標簽 label="賬號", # 驗證器 validators=[ DataRequired('請輸入用戶名') ], description="賬號", # 附加選項,會自動在前端判別 render_kw={ "class":"form-control", "placeholder":"請輸入賬號!", "required":'required' #表示輸入框不能為空,並有提示信息 } ) pwd = PasswordField( # 標簽 label="密碼", # 驗證器 validators=[ DataRequired('請輸入密碼') ], description="密碼",
# 附加選項(主要是前端樣式),會自動在前端判別 render_kw
={ "class": "form-control", "placeholder": "請輸入密碼!", "required": 'required'     # 表示輸入框不能為空 } ) submit = SubmitField( label="登錄", render_kw={ "class": "btn btn-primary btn-block btn-flat", } )

 

視圖函數views.py

from . import adminbapp    ##導入app
from flask import render_template,redirect,url_for,flash,session,request
from admin.forms import LoginForm      #引入forms.py文件
from models import Admin            #導入數據庫模型
from functools import wraps      #導入裝飾器模塊
from movie_project import db      #引入sqlalchemy實例化對象

#登錄驗證裝飾器
def login_required(func):
    @wraps(func)
def decorated_function(*args, **kwargs):
if session.get('admin'):         #驗證session
return func(*args, **kwargs)
else:
return redirect(url_for('admin.login'))
return decorated_function

@adminbapp.route('/login/',methods=['GET','POST'])
def login():
    forms = LoginForm()                #實例化forms
    if forms.validate_on_submit():       #提交的時候進行驗證,如果數據能被所有驗證函數接受,則返回true,否則返回false
        data = forms.data                #獲取form數據信息(包含輸入的用戶名(account)和密碼(pwd)等信息),這里的account和pwd是在forms.py里定義的
        admin = Admin.query.filter_by(name=data["account"]).first()    #查詢表信息admin表里的用戶名信息 if admin == None:
            flash("賬號不存在")                            #操作提示信息,會在前端顯示 return redirect(url_for('admin.login'))
        elif admin != None and not admin.check_pwd(data["pwd"]):            #這里的check_pwd函數在models 下Admin模型下定義
            flash("密碼錯誤")
            return  redirect(url_for('admin.login'))
        session['admin'] = data['account']                          #匹配成功,添加session
        return redirect(request.args.get('next') or url_for('admin.index'))  #重定向到首頁 return render_template('admin/login.html',form=forms)

 

數據庫模型models.py

class Admin(db.Model):
    __tablename= 'admin'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False, unique=True)  # unique代表不能重復,唯一的
    pwd = db.Column(db.String(100), nullable=False)
    is_super = db.Column(db.SmallInteger)  #是否為超級管理員
    role_id = db.Column(db.Integer,db.ForeignKey('role.id'))
    addtime = db.Column(db.DateTime, index=True, default=datetime.datetime.now)

    adminlogs = db.relationship('Adminlog',backref='admin')
    adminoption = db.relationship('Oplogs', backref='admin')

    def __repr__(self):
        return '<Admin %r>' % self.name
  
   #定義密碼驗證函數
def check_pwd(self,pwd): from werkzeug.security import check_password_hash    #由於密碼是加密的,所以要引入相應的加密函數 return check_password_hash(self.pwd,pwd)

 

前端 login.html

<div class="login-box-body">
        {% for msg in get_flashed_messages() %}          <!--這里對應視圖函數里定義的提示信息 flash--> <p class="login-box-msg" style="color: red;">{{ msg }}</p>    <!--信息在前端顯示-->
        {% endfor %}
        <form method="POST" id="form-data">              <!--使用form,這里可以不用寫action-->
            <div class="form-group has-feedback">
                {{ form.account }}             <!--常規情況下,這里應該為一個input框,用來定義用戶輸入,由於在forms里已經定義,這里直接調用就行--> <span class="glyphicon glyphicon-envelope form-control-feedback"></span>
                {% for err in form.account.errors %}        <!--錯誤信息--> <div class="col-md-12">

                        <span style="color: red">{{ err }}</span>  <!--顯示錯誤信息-->
                    </div>
                {% endfor %}
            </div>
            <div class="form-group has-feedback">
                {{ form.pwd }}                <!--同上面的用戶輸入--> <span class="glyphicon glyphicon-lock form-control-feedback"></span>
                {% for err in form.pwd.errors %}            <!--pwd輸入錯誤的提示信息--> <div class="col-md-12">
                        <font style="color: red">{{ err }}</font>
                    </div>
                {% endfor %}
            </div>
            <div class="row">
                <div class="col-xs-8">
                </div>
                <div class="col-xs-4">
                    {{ form.submit }}            <!--提交按鈕-->
                    {{ form.csrf_token }}          <!--csrftoken必須要寫,同時還要設置 app的secret_key--> </div>
            </div>
        </form>
    </div>

 

配置secret_key

import os
app.config['SECRET_KEY'] = os.urandom(24)

 

實例之會員注冊功能

forms.py表單文件

#!/usr/bin/env python
#-*-coding:utf-8-*-

from flask_wtf import FlaskForm                 #FlaskForm 為表單基類
from wtforms import StringField,PasswordField,SubmitField     #導入字符串字段,密碼字段,提交字段
from wtforms.validators import DataRequired,ValidationError,Email,Regexp,EqualTo
from models import User

class RegistUser(FlaskForm):
    account = StringField(
        # 標簽
        label="昵稱",
        # 驗證器
        validators=[
            DataRequired('請輸入昵稱')
        ],
        description="昵稱",
        # 附加選項,會自動在前端判別
        render_kw={
            "class":"form-control",
            "placeholder":"請輸入昵稱",
            #"required":'required'               #表示輸入框不能為空
        }
    )

    email = StringField(
        label="郵箱",
        # 驗證器
        validators=[
            DataRequired('請輸入郵箱'),
            Email('郵箱格式不正確')            #用Email方法驗證郵箱格式
        ],
        description="郵箱",
        # 附加選項,會自動在前端判別
        render_kw={
            "class": "form-control",
            "placeholder": "請輸入郵箱!",
            #"required": 'required'        # 表示輸入框不能為空
        }
    )

    phone = StringField(
        label="手機",
        # 驗證器
        validators=[
            DataRequired('請輸入手機號碼'),
            Regexp("1[3578]\d{9}", message="手機格式不正確")      # 用正則匹配手機號碼規則
        ],
        description="手機",
        # 附加選項,會自動在前端判別
        render_kw={
            "class": "form-control",
            "placeholder": "請輸入手機號碼",
            #"required": 'required'        # 表示輸入框不能為空
        }
    )

    pwd = PasswordField(
        # 標簽
        label="密碼",
        # 驗證器
        validators=[
            DataRequired('請輸入密碼')
        ],
        description="密碼",
        # 附加選項,會自動在前端判別
        render_kw={
            "class": "form-control",
            "placeholder": "請輸入密碼!",
            #"required": 'required'  # 表示輸入框不能為空
        }
    )

    repwd = PasswordField(
        # 標簽
        label="確認密碼",
        # 驗證器
        validators=[
            DataRequired('確認密碼'),
            EqualTo('pwd',message="兩次密碼輸入不一致")        #判斷兩次輸入的密碼是否一致
        ],
        description="確認密碼",
        # 附加選項,會自動在前端判別
        render_kw={
            "class": "form-control",
            "placeholder": "確認密碼",
            #"required": 'required'  # 表示輸入框不能為空
        }
    )
    submit = SubmitField(
        label="注冊",
        render_kw={
            "class": "btn btn-success btn-block",
        }
    )

    # 賬號認證,自定義驗證器,判斷輸入的值是否唯一
    def validate_name(self, filed):
        name = filed.data
        account = User.query.filter_by(name=name).count()
        if account == 1:
            raise ValidationError("昵稱已經存在")

    def validate_email(self, filed):
        emails = filed.data
        account = User.query.filter_by(email=emails).count()
        if account == 1:
            raise ValidationError("郵箱已經注冊")

    def validate_phone(self, filed):
        phones = filed.data
        account = User.query.filter_by(phone=phones).count()
        if account == 1:
            raise ValidationError("手機號已經注冊")

 

視圖函數views.py

@homebapp.route("/register/",methods=['GET','POST'])
def register():
    form = RegistUser()   #實例化form

    if form.validate_on_submit():      #提交時
        data = form.data
        user = User(
            name=data['account'],
            email=data['email'],
            phone = data['phone'],
            pwd=generate_password_hash(data['pwd']),
            uuid = uuid.uuid4().hex
        )
        db.session.add(user)
        db.session.commit()
        flash("注冊成功",'ok')
    return render_template("home/register.html",form=form)

 

models.py

class User(db.Model):
    __tablename__ ="user"
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(100),nullable=False,unique=True)  #unique代表不能重復,唯一的
    pwd = db.Column(db.String(100),nullable=False)
    email = db.Column(db.String(64),nullable=False,unique=True)
    phone = db.Column(db.String(11),nullable=False,unique=True)
    info = db.Column(db.Text)
    face = db.Column(db.String(100))         #頭像
    addtime = db.Column(db.DateTime,index=True,default=datetime.datetime.now)
    uuid = db.Column(db.String(255))

    userlogs = db.relationship('UserLog',backref='user') #外鍵關系關聯
    comments = db.relationship('Comment',backref='user')
    movicols = db.relationship('Moviecol', backref='user')

    def __repr__(self): #定義返回的類型
        return '<user %r>' % self.name

    def check_pwd(self,pwd):                    #驗證密碼 from werkzeug.security import check_password_hash
        return  check_password_hash(self.pwd,pwd)

 

前端register.html

<div class="panel-body">
                    {% for msg in get_flashed_messages(category_filter=['err']) %}    <!--flash信息-->
                        <p style="color: red">{{ msg }}</p>
                    {% endfor %}
                    {% for msg in get_flashed_messages(category_filter=['ok']) %}
                        <p style="color: green">{{ msg }}</p>
                    {% endfor %}
                    <form role="form" method="POST">
                        <fieldset>
                            <div class="form-group">
                                <label for="input_name"><span class="glyphicon glyphicon-user"></span>&nbsp;昵稱</label>
                                {{ form.account }}
                            </div>
                            {% for err in form.account.errors %}
                                <div class="col-md-12">
                                    <span style="color: red">{{ err }}</span>
                                </div>
                            {% endfor %}
                            <div class="form-group">
                                <label for="input_email"><span class="glyphicon glyphicon-envelope"></span>&nbsp;郵箱</label>
                                {{ form.email }}
                            </div>
                            {% for err in form.email.errors %}
                                <div class="col-md-12">
                                    <span style="color: red">{{ err }}</span>
                                </div>
                            {% endfor %}
                            <div class="form-group">
                                <label for="input_phone"><span class="glyphicon glyphicon-phone"></span>&nbsp;手機</label>
                                {{ form.phone }}
                            </div>
                            {% for err in form.phone.errors %}
                                <div class="col-md-12">
                                    <span style="color: red">{{ err }}</span>
                                </div>
                            {% endfor %}
                            <div class="form-group">
                                <label for="input_password"><span class="glyphicon glyphicon-lock"></span>&nbsp;密碼</label>
                                {{ form.pwd }}
                            </div>
                            {% for err in form.pwd.errors %}
                                <div class="col-md-12">
                                    <span style="color: red">{{ err }}</span>
                                </div>
                            {% endfor %}
                            <div class="form-group">
                                <label for="input_repassword"><span class="glyphicon glyphicon-lock"></span>&nbsp;確認密碼</label>
                                {{ form.repwd }}
                            </div>
                            {% for err in form.repwd.errors %}
                                <div class="col-md-12">
                                    <span style="color: red">{{ err }}</span>
                                </div>
                            {% endfor %}
                            {{ form.csrf_token }}
                            {{ form.submit }}
                        </fieldset>

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM