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__.pyfrom .user import Register,Login#user.pyfrom flask_wtf import FlaskFormfrom wtforms import SubmitField,StringField,PasswordField,BooleanField,ValidationErrorfrom App.models import Userfrom wtforms.validators import DataRequired,Email,Length,EqualToclass 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__.pyfrom .user import User#user.pyfrom App.extensions import dbfrom werkzeug.security import generate_password_hash,check_password_hashfrom itsdangerous import TimedJSONWebSignatureSerializer as Seralizefrom flask import current_appfrom flask_login import UserMixinfrom App.extensions import login_managerclass 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_loaderdef user_loader(uid): return User.query.get(int(uid))
3 views目录
#__init__.pyfrom .user import userfrom .main import mainBluePrint = [ (user,''), (main,'')]def config_blueprint(app): for blueprint,prefix in BluePrint: app.register_blueprint(blueprint,url_prefix=prefix) #main.pyfrom flask import Blueprint,render_templatemain = Blueprint('main',__name__)@main.route('/')def index(): return render_template('main/index.html')#user.pyfrom flask import Blueprint,render_template,flash,redirect,url_forfrom App.models import Userfrom App.forms import Register,Loginfrom App.extensions import dbfrom App.email import send_mailfrom flask_login import login_user,logout_user,current_useruser = 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//')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_templatefrom App.settings import configfrom App.extensions import config_extentionsfrom 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_appfrom flask_mail import Messagefrom threading import Threadfrom App.extensions import maildef 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 Bootstrapfrom flask_sqlalchemy import SQLAlchemyfrom flask_migrate import Migratefrom flask_login import LoginManagerfrom 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 Managerfrom App import create_appfrom 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