Flask博客类登录注册验证模块代码(十四)

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','15858017847@163.com')
    MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD','mm22kk11')

#测试配置
class TestingConfig(Config):
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:xxx@127.0.0.1:3306/testing'

#开发配置
class DevelopmentConfig(Config):
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:xxx@127.0.0.1:3306/blogModel'

#生产配置
class ProductionConfig(Config):
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:xxx@127.0.0.1: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

posted @ 2018-06-10 19:09  诚实善良小郎君  阅读(492)  评论(0编辑  收藏  举报