今天我们要做的就是把一个整体的框架必备的模板给搭建好
下面会一一讲解序号文件的含义
1. static
这里static存放静态文件,是用来把基本的样式和js文件存放的,我们的flask的url_for就需要用到这个文件夹
2.bootstarp
bootstarp这个模板一般是html用到了一些组件,所以得放这个文件
3.cs
css文件夹一般放的都是一些样式
4.images
images这个文件夹一般都是放一些图片信息
5.jquery
一般页面的动态用jquery访问比较方便
6.js
js文件一般都放一些动态交互的JavaScript代码
7.templates
templates代表的是模板文件,一般放的都是一些网页html代码文件,一般都是用render_template来进行模板渲染结果页面
8、9、10
这几个都是登录注册页面的代码,可以直接看到登录注册页面是怎么样
11app.py
app.py 文件在 Flask 项目中扮演着非常重要的角色。它主要完成以下几个任务:
创建 Flask 应用程序实例:app = Flask(name) 这行代码创建了一个 Flask 应用程序对象。在 Flask 中,name 参数通常用于确定应用程序的根路径和静态文件的位置1。
定义路由和视图函数:@app.route(‘/’) 是一个装饰器,它将 URL 映射到下面的函数,这个函数就是视图函数。当你访问网站的 / 目录时,会执行这个函数,并将这个函数的返回值返回给浏览器2。
启动应用程序:if name == ‘main’: app.run() 这段代码会启动 Flask 的开发服务器,并运行应用程序2。
此外,app.py 文件还可以用于连接数据库3。总的来说,app.py 文件是 Flask 项目的核心,它负责创建应用、定义路由和视图函数、以及启动应用。
小总结:1.一般定义路由和视图函数 2.一般定义启动应用程序 3.连接数据库
12config.py
一般都是一些数据库的连接和配置都在这里面
13.exts.py
14model.py一般是一些模型文件一般都和数据库的表格有关
到这里我们的项目的一个基本大体框架搭建好了
现在开始第一步
建立user模型,但是要建立user模型,我们得先连接数据库
到这里我们就完成了数据库的建立,在建立好了数据库,我们就得在config.py中完成数据库的配置工作
#配置数据库
# HOSTNAME = 主机名
# PROT = "端口号“
# DATABASE = "数据库名称"
# USERNAME = ”用户名"
# PASSWORF = "密码"
# DB_URI = "mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)"
# SQLALCHEMY_DATABASE_URL = DB_URI
HOSTNAME = "127.0.0.1"
PORT = "3306"
DATABASE = "zhiliaooa"
USERNAME = "root"
PASSWORD = "064810"
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URI
然后暂时的model.py的代码
from exts import db
from datetime import datetime
class UserModel(db.Model):
__tablename__ = 'user' # 在数据库中建了一张名为user的表,其中表含有id,username,password,email,join_time
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # primary_key为主键 autoincrement = True 表示自动增加
username = db.Column(db.String(400), nullable=False) # 属性或者列名一般都是(类别,可不可空,default = “”缺省值)
password = db.Column(db.String(400), nullable=False)
email = db.Column(db.String(400), nullable=False, unique=True)
join_time = db.Column(db.DateTime, default=datetime.now) # datatime.now这个表示调用这个函数
然后我们需要把它迁移到数据库中
迁移三部曲
- flask db init(只有第一次迁移才用,之后都不需要第一部了)
- flask db migrate
- flask db upgrade
这样表就创建完成了
@bp.route('/login',methods = ['GET','POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
return '这是提交登录表单页面'
@bp.route('/register',methods = ['GET','POST'])
def register():
if request.method == 'GET':
return render_template('register.html')
else:
return '这是提交注册表单页面'
然后用模板渲染的方式返回登陆注册页面
在登录注册页面我们有邮箱验证,这个时候,我们就得来配置我们的邮箱,那么我的flask自学记录里面有过flask前端的邮箱的配置,所以我在这就不了赘婿了
邮箱配置
MAIL_SERVER = 'smtp.qq.com'
MAIL_USE_SSL = True
MAIL_PORT = 465
MAIL_USERNAME = "990637259@qq.com"
MAIL_PASSWORD = "gfepnbqwunagbfdf"
MAIL_DEFAULT_SENDER = "990637259@qq.com"
mail_text
@bp.route('/mail/test')
def mail_test():
message = Message(subject='邮箱主题',recipients=['xxxxxxx@qq.com'],body='正文内容')
print(message)
mail.send(message)
return '发送成功!'
# mail.send(message)
# return "邮件发送成功!"
# # subject 表示发送主题
# # recipients 表示发送对象(发送的地址)
# # body 表示发送的内容
然后我们就得编写发送邮箱验证码的代码
- get_email_captcha代码
@bp.route("/captcha/email")
def get_email_captcha():#发送验证码 随机的四位
####生成验证码
# 我们有两种传参方式
# /captcha/email/<email> 根据路径传参 用<>来传递参数
# /captcha/email?email=2036801580@qq.com
email = request.args.get("email")
source = 4*string.digits#'0123456789012345678901234567890123456789'
captcha = random.sample(source,4)#随机四位验证码长度
captcha =''.join(captcha)#把列表变成字符串 就是列表袁术拼接
###发送验证码
message = Message(subject='hello,goodmoring!!!!',recipients = [email],body = f"GOOD MORNING:{captcha}")
mail.send(message)
# 把邮箱和验证码传入到数据库中
#memcached/redis 缓存 验证码在服务器也得存储一份
#用数据库中存储验证码,偏慢一点
email_catpcha = EmailCaptchaModel(email=email,captcha=captcha)
db.session.add(email_catpcha)
db.session.commit()
#restful api 返回数据统一一个格式
# {code :200/400/500,message:"“,data:{}}
return jsonify({'code':200,"messzge":"",'data':None})
# return f"验证码为{captcha}"
代码解析:
string.digits#‘0123456789’ 这里我们用string.digits可以表示0-9的字符然后进行字符串拼接(source = 4*string.digits),再然后就random 4位出来就可以选择好我们的验证码,然后再message进行发送,最后将其存入到数据库中
完成了代码后,我们就得完成表单验证这样我们才知道填入的验证码就是我发送的验证码,这时候就得进行数据库的查询和匹配
可以看一下如何实现的
@bp.route('/register',methods=['GET','POST'])
def register():
if request.method == 'GET':
return render_template("register.html")# 要导入render_template就可以使用渲染
else:
form = RegisterForm(request.form) #得到一个/RegisterForm对象
if form.validate():
email = form.email.data
password = form.password.data
username = form.username.data
user = UserModel(email = email,password = generate_password_hash(password),username= username)
db.session.add(user)
db.session.commit()
return redirect(url_for('auth.login'))
else:
print(form.errors)
return redirect(url_for('auth.register'))
这里就完成了表单验证
先写到这里,中途验证码倒计时出了点bug,有点晚,就先睡了,明天解决
第二天继续学习
首先先得解决掉昨天晚上的点击获取验证码开始倒计时的功能
- 首先再register.html中要得导入jquery和js文件,这里要注意jquery要放在第一个script下,因为js代码要用到$,所以还是得放到第一个才行。(昨天主要是没有导入两个库和jquery位置没有放好)
我们可以看一下register.js代码
function bindEmailCaptchaClick(){
$("#captcha-btn").click(function (event){
// $this:代表的是当前按钮的jquery对象
var $this = $(this);
// 阻止默认的事件
event.preventDefault();
var email = $("input[name='email']").val();
alert(email)
$.ajax({
// http://127.0.0.1:500
// /auth/captcha/email?email=xx@qq.com
url: "/auth/captcha/email?email="+email,
method: "GET",
success: function (result){
var code = result['code'];
if(code == 200){
var countdown = 5;
// 开始倒计时之前,就取消按钮的点击事件
$this.off("click");
var timer = setInterval(function (){
$this.text(countdown);
countdown -= 1;
// 倒计时结束的时候执行
if(countdown <= 0){
// 清掉定时器
clearInterval(timer);
// 将按钮的文字重新修改回来
$this.text("获取验证码");
// 重新绑定点击事件
bindEmailCaptchaClick();
}
}, 1000);
// alert("邮箱验证码发送成功!");
}else{
alert(result['message']);
}
},
fail: function (error){
console.log(error);
}
})
});
}
// 整个网页都加载完毕后再执行的
$(function (){
bindEmailCaptchaClick();
});
其中
$(function (){
代码
})
这里面的代码就是再整个页面渲染结束后,才开始执行这个函数里面的代码
到这里我们就先完成了一小段任务就是发送验证码的基本任务
接下来我们要完成注册表单验证,就是每个input要以一定的限制比如长度至少为2个,完成表单任务后,就是点击提交就有POST请求,然后再后端接收到表单数据,进行数据库存储和验证码验证
首先表单验证如下
import wtforms
from wtforms.validators import Email,EqualTo,Length,InputRequired
from models import UserModel
from models import EmailCaptchaModel
from exts import db
# Form 主要用来验证前端提交的数据是否符合要求
class RegisterForm(wtforms.Form):
email = wtforms.StringField(validators=[Email(message='邮箱格式错误!')])
captcha = wtforms.StringField(validators=[Length(min = 4,max = 400,message = 'yzm错误!')])
username = wtforms.StringField(validators=[Length(min= 2,max = 400,message='用户名错误!')])
password = wtforms.StringField(validators=[Length(min = 2,max = 400,message="密码格式错误!")])
password_confirm = wtforms.StringField(validators=[EqualTo('password')])
# 我们也可以用jquery就像获取qq邮箱一样,来获取各个表单,但这个就得一一找到input对应的id然后获取
# 自定义验证
#1.邮箱是否已近被注册了
def validate_email(self,field): #//验证是否已经注册了
email = field.data
user = UserModel.query.filter_by(email=email).first()
print(type(user))
if user:
raise wtforms.ValidationError(message='该邮箱已经被注册了')#这里的抛出错误页面信息,必须是在前端页面展示的
# 2.验证码是否正确 注这里field是传过来的参数 就是上面的email captcha,username,password之类的
def validate_captcha(self,field):#这里是表单类的验证验证码的函数,所以self代表表单对象
captcha = field.data
# EmailCaptchaModel.query.filter_by(captcha)
email = self.email.data# 最终获得表单的email的data
captcha_model = EmailCaptchaModel.query.filter_by(email = email,captcha = captcha).first()
if not captcha_model:
raise wtforms.ValidationError(message='验证码输入错误!')
# else: 最好写个脚本,定期的清理一次
# #to da 删除验证码
# db.session.delete(captcha)
# db.session.commit()
下面是蓝图注册的表单验证
首先如果是post就会进行表单验证,这时候我们得建立一个Register的表单,其中表单名字必须和input name标签名字一样
下面就是表单的建立
class RegisterForm(wtforms.Form):
email = wtforms.StringField(validators=[Email(message='邮箱格式错误!')])
captcha = wtforms.StringField(validators=[Length(min = 4,max = 400,message = 'yzm错误!')])
username = wtforms.StringField(validators=[Length(min= 2,max = 400,message='用户名错误!')])
password = wtforms.StringField(validators=[Length(min = 2,max = 400,message="密码格式错误!")])
password_confirm = wtforms.StringField(validators=[EqualTo('password')])
# 我们也可以用jquery就像获取qq邮箱一样,来获取各个表单,但这个就得一一找到input对应的id然后获取
# 自定义验证
#1.邮箱是否已近被注册了
def validate_email(self,field): #//验证是否已经注册了
email = field.data
user = UserModel.query.filter_by(email=email).first()
print(type(user))
if user:
raise wtforms.ValidationError(message='该邮箱已经被注册了')#这里的抛出错误页面信息,必须是在前端页面展示的
# 2.验证码是否正确 注这里field是传过来的参数 就是上面的email captcha,username,password之类的
def validate_captcha(self,field):#这里是表单类的验证验证码的函数,所以self代表表单对象
captcha = field.data
# EmailCaptchaModel.query.filter_by(captcha)
email = self.email.data# 最终获得表单的email的data
captcha_model = EmailCaptchaModel.query.filter_by(email = email,captcha = captcha).first()
if not captcha_model:
raise wtforms.ValidationError(message='验证码输入错误!')
# else: 最好写个脚本,定期的清理一次
# #to da 删除验证码
# db.session.delete(captcha)
# db.session.commit()
建立完成之后,因为这个是注册页面,我们要拿取表单数据,然后把数据存储到数据库中,再跳转到登陆页面
@bp.route('/register',methods = ['GET','POST'])
def register():
if request.method == 'GET':
return render_template('register.html')
else:
form = RegisterForm(request.form)
if form.validate():
email = form.email.data
password = form.password.data
username = form.username.data
user = UserModel(email = email,password = generate_password_hash(password),username=username)
db.session.add(user)
db.session.commit()
return redirect(url_for('auth.login'))
else:
print('**************************')
print(form.errors)
return redirect(url_for('auth.register'))
接下来我们看登录页面的代码逻辑
首先一样,先进行表单验证,获取表单数据,然后UserModel.query.filter_by(email = email).first()查询数据库中是否有该数据,如果有,就得进行密码检查看密码是否一致,一致的话,存储cookie,然后就是进入到首页
def login():
if request.method == 'GET':
return render_template('login.html')
else:
form = Loginform(request.form)
if form.validate():
### 进行表单验证
email = form.email.data
password = form.password.data
user = UserModel.query.filter_by(email = email).first()
if not user:
print('邮箱账户不存在')
return redirect(url_for('auth.register'))
else:
### 就是邮箱存在,这时候我们得进行密码验证,又因为我们对密码进行了加密,所以得进行一系列的操作才行
if check_password_hash(user.password,password):
# cooike 不适合存储太多数据,只适合存储少量数据 饼干碎屑 一般用于用户授权信息
# flask的session是经过加密后存储在cookie中的
session['user_id'] = user.id
return redirect('/') # 找到根目录 就可以完成
else:
print('登陆失败!')
return redirect(url_for('auth.login'))
else:
return f'{form.errors}'
这里首页代码的前端还没有完全写好哈哈哈哈,就先凑合看,毕竟我们要的是整体框架没有问题
这里是数据库存储区域,可以看到账号密码都已经存储进来了(嘻嘻账号密码是加密的)
到这里就完成了前后端的登陆注册页面