Flask博客類登錄註冊驗證模塊代碼(十四)
阿新 • • 發佈:2018-06-10
extent down rms 地址 generate targe 文件系統 退出 生產
1 文件系統
blog #博客類
App
forms #表單
__init__.py
user.py
models #模型
__init__.py
user.py
static #靜態文件
templates #模板
common #基類模板
base.html
email #郵件
email.html
errors #錯誤
error.html
main #主頁
index.html
user #用戶登錄註冊
login.html
register.html
views #視圖藍本
__init__.py
main.py
user.py
__init__.py
email.py #郵件
extensions.py #擴展庫
settings.py #系統配置
migrations #遷移文件
manage.py #啟動文件
2 forms目錄下
#__init__.py
from .user import Register,Login
#user.py
from flask_wtf import FlaskForm
from wtforms import SubmitField,StringField,PasswordField,BooleanField,ValidationError
from App.models import User
from wtforms.validators import DataRequired,Email,Length,EqualTo
class Register(FlaskForm):
username = StringField(‘用戶名‘,validators=[DataRequired(message=‘用戶名不能為空...‘),Length(min=6,max=12,message=‘長度為6-12位‘)],render_kw={‘placeholder‘:‘請輸入用戶名...‘,‘maxlength‘:12})
password = PasswordField(‘密碼‘,validators=[DataRequired(message=‘密碼不能為空‘),Length(min=6,max=12,message=‘長度為6-12位‘),EqualTo(‘confirm‘,message=‘倆次密碼不一致‘)],render_kw={‘placeholder‘:‘請輸入密碼...‘,‘maxlength‘:12})
confirm = PasswordField(‘密碼‘,validators=[DataRequired(message=‘密碼不能為空‘),Length(min=6,max=12,message=‘長度為6-12位‘)],render_kw={‘placeholder‘:‘請輸入確認密碼...‘,‘maxlength‘:12})
email = StringField(‘郵箱‘,validators=[Email(message=‘請輸入正確的郵箱‘)],render_kw={‘placeholder‘:‘請輸入郵箱...‘,‘maxlength‘:30})
submit = SubmitField(‘註冊‘)
# 自定義驗證器 用戶名是否存在
def validate_username(self, field):
if User.query.filter(User.username == field.data).first():
raise ValidationError(‘該用戶已註冊!!!‘)
# 自定義驗證器 郵箱是否存在
def validate_email(self, field):
if User.query.filter(User.email == field.data).first():
raise ValidationError(‘該郵箱已註冊!!!‘)
class Login(FlaskForm):
username = StringField(‘用戶名‘,validators=[DataRequired(message=‘用戶名不能為空...‘), Length(min=6, max=12, message=‘長度為6-12位‘)],render_kw={‘placeholder‘: ‘請輸入用戶名...‘, ‘maxlength‘: 12})
password = PasswordField(‘密碼‘,validators=[DataRequired(message=‘密碼不能為空‘),Length(min=6, max=12, message=‘長度為6-12位‘)],render_kw={‘placeholder‘: ‘請輸入密碼...‘, ‘maxlength‘: 12})
remember = BooleanField(‘記住我‘)
submit = SubmitField(‘登錄‘)
3 models目錄下
#__init__.py
from .user import User
#user.py
from App.extensions import db
from werkzeug.security import generate_password_hash,check_password_hash
from itsdangerous import TimedJSONWebSignatureSerializer as Seralize
from flask import current_app
from flask_login import UserMixin
from App.extensions import login_manager
class User(UserMixin,db.Model):
__tablename__ = ‘user‘
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(12),index=True)
password_hash = db.Column(db.String(128))
sex = db.Column(db.Boolean,default=True)
age = db.Column(db.Integer)
email = db.Column(db.String(40))
icon = db.Column(db.String(70),default=‘default.jpg‘)
#當期賬戶激活狀態
confirm = db.Column(db.Boolean,default=False)
@property
def password(self):
raise ValueError
#密碼設置為hash
@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
#生成token的方法
def generate_token(self):
s = Seralize(current_app.config[‘SECRET_KEY‘])
return s.dumps({‘id‘:self.id})
#檢測token的方法
@staticmethod
def check_token(token):
s = Seralize(current_app.config[‘SECRET_KEY‘])
# print(s)
#從當前的token中拿出字典
try:
id = s.loads(token)[‘id‘]
except:
return False
#獲取id對應的user數據
u = User.query.get(id)
if not u:
return False
if not u.confirm:
print(u.confirm)
u.confirm = True
print(u.confirm)
db.session.add(u)
return True
#驗證密碼
def check_password_hash(self,password):
return check_password_hash(self.password_hash,password)
#登錄認證的回調 保持數據的一致性
@login_manager.user_loader
def user_loader(uid):
return User.query.get(int(uid))
3 views目錄
#__init__.py
from .user import user
from .main import main
BluePrint = [
(user,‘‘),
(main,‘‘)
]
def config_blueprint(app):
for blueprint,prefix in BluePrint:
app.register_blueprint(blueprint,url_prefix=prefix)
#main.py
from flask import Blueprint,render_template
main = Blueprint(‘main‘,__name__)
@main.route(‘/‘)
def index():
return render_template(‘main/index.html‘)
#user.py
from flask import Blueprint,render_template,flash,redirect,url_for
from App.models import User
from App.forms import Register,Login
from App.extensions import db
from App.email import send_mail
from flask_login import login_user,logout_user,current_user
user = Blueprint(‘user‘,__name__)
#註冊
@user.route(‘/register/‘,methods=[‘GET‘,‘POST‘])
def register():
form = Register()
if form.validate_on_submit():
#實例化user模型類
u = User(username=form.username.data,password=form.password.data,email=form.email.data)
db.session.add(u)
db.session.commit()
#生成token
token = u.generate_token()
#發送郵件
send_mail(‘郵件激活‘,form.email.data,‘activate‘,username=form.username.data,token=token)
flash(‘註冊成功請去郵箱中激活‘)
#跳轉到登錄頁面
return redirect(url_for(‘user.login‘))
return render_template(‘user/register.html‘,form=form)
@user.route(‘/activate/<token>/‘)
def activate(token):
if User.check_token(token):
flash(‘激活成功 請登錄‘)
return redirect(url_for(‘user.login‘))
else:
flash(‘激活失敗‘)
return redirect(url_for(‘main.index‘))
#登錄
#加一個時間的驗證 如果輸入錯誤超過三次 把激活改為False
@user.route(‘/login/‘,methods=[‘GET‘,‘POST‘])
def login():
form = Login()
if form.validate_on_submit():
u = User.query.filter_by(username=form.username.data).first()
if not u:
flash(‘該用戶不存在‘)
elif not u.confirm:
flash(‘該用戶還沒激活!!!‘)
elif u.check_password_hash(form.password.data):
flash(‘登錄成功!‘)
login_user(u,remember=form.remember.data)
return redirect(url_for(‘main.index‘))
else:
flash(‘請輸入正確的密碼‘)
return render_template(‘user/login.html‘,form=form)
#退出登錄
@user.route(‘/logout/‘)
def logout():
logout_user()
flash(‘退出成功!‘)
return redirect(url_for(‘main.index‘))
4 APP應用下
__init__.py
from flask import Flask,render_template
from App.settings import config
from App.extensions import config_extentions
from App.views import config_blueprint
#利用工廠函數統一在調用時綁定
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config_extentions(app)
config_blueprint(app)
errors(app)
return app
#錯誤頁面
def errors(app):
@app.errorhandler(404)
def page_not_found(e):
return render_template(‘errors/error.html‘,error=e)
@app.errorhandler(500)
def server_error(e):
return render_template(‘errors/error.html‘, error=e)
email.py
from flask import render_template,current_app
from flask_mail import Message
from threading import Thread
from App.extensions import mail
def async_send_mail(app,msg):
#獲取文件上下文
with app.app_context():
mail.send(message=msg)
#定義發送郵件函數
def send_mail(subject,to,tem,**kwargs):
app = current_app._get_current_object()
msg = Message(subject=subject, recipients=[to], sender=app.config[‘MAIL_USERNAME‘])
msg.html = render_template(‘email/‘+tem+‘.html‘,**kwargs)
send = Thread(target=async_send_mail,args=(app,msg))
send.start()
extensions.py
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_mail import Mail
#擴展庫的實例化
bootstrap = Bootstrap()
db = SQLAlchemy()
migrate = Migrate(db=db)
login_manager = LoginManager()
mail = Mail()
#統一進行app的初始化操作
def config_extentions(app):
bootstrap.init_app(app)
db.init_app(app)
migrate.init_app(app=app)
login_manager.init_app(app=app)
mail.init_app(app)
login_manager.login_view = ‘user.login‘
login_manager.login_message = ‘請登錄在訪問‘
login_manager.session_protection = ‘strong‘
settings.py
import os
#所有環境配置的基類
class Config:
SECRET_KEY = ‘xiafsadwsda‘
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
MAIL_SERVER = os.environ.get(‘MAIL_SERVER‘,‘smtp.163.com‘)
MAIL_USERNAME = os.environ.get(‘MAIL_USERNAME‘,‘[email protected]‘)
MAIL_PASSWORD = os.environ.get(‘MAIL_PASSWORD‘,‘mm22kk11‘)
#測試配置
class TestingConfig(Config):
SQLALCHEMY_DATABASE_URI = ‘mysql+pymysql://root:[email protected]:3306/testing‘
#開發配置
class DevelopmentConfig(Config):
SQLALCHEMY_DATABASE_URI = ‘mysql+pymysql://root:[email protected]:3306/blogModel‘
#生產配置
class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = ‘mysql+pymysql://root:[email protected]:3306/development‘
#一個配置的字典
config = {
‘development‘:DevelopmentConfig,
‘production‘:ProductionConfig,
‘test‘:TestingConfig,
‘default‘:DevelopmentConfig
}
manage.py
from flask_script import Manager
from App import create_app
from flask_migrate import MigrateCommand
#調用創建create_app函數
app = create_app(‘default‘)
manager = Manager(app)
manager.add_command(‘db‘,MigrateCommand)
if __name__ == ‘__main__‘:
manager.run()
html頁面的代碼比較多,有需要的可以訪問源碼地址,感謝閱讀!!
GitHub源碼地址:https://github.com/whyjust/blog
Flask博客類登錄註冊驗證模塊代碼(十四)