flask实战(问答平台)

问答平台项目结构搭建

先创建一个配置文件config.py,后面有些配置写在这里
在这里插入图片描述

#app.py
from flask import Flask
import configapp = Flask(__name__)
#绑定配置文件
app.config.from_object(config)@app.route('/')
def hello_world():  # put application's code herereturn 'Hello World!'if __name__ == '__main__':app.run()

再新建一个exts.py和models.py

#exts.py
#flask-sqlalchemy
from flask_sqlalchemy import SQLAlchemydb=SQLAlchemy()#models.py
from exts import dbclass UserModel(db.Model):pass#app.py
from flask import Flask
import config
from exts import db
from models import UserModelapp = Flask(__name__)
#绑定配置文件
app.config.from_object(config)#可以让你先创建,再绑定
db.init_app(app)@app.route('/')
def hello_world():  # put application's code herereturn 'Hello World!'if __name__ == '__main__':app.run()

防止循环引用,如果不加exts.py会导致下面这种情况
在这里插入图片描述
加了就可以变成这样子

在这里插入图片描述
下面设置蓝图,用来做模块化的
在这里插入图片描述

在这里插入图片描述
再在这里新建两个py文件,一个是auth.py和授权相关的,一个是qa.py和问答相关的

#auth.py
from flask import Blueprint# /auth,后面所有的路由都是以这个开头,比如/auth/login
bp=Blueprint("auth",__name__,url_prefix="/auth")@bp.route("/login")
def login():pass#qa.py
from flask import Blueprintbp=Blueprint("qa",__name__,url_prefix="/")@bp.route("/")
def index():pass

再在app.py中导入和绑定

#app.py
from flask import Flask
import config
from exts import db
from models import UserModel
from blueprints.qa import bp as qa_bp
from blueprints.auth import bp as auth_bpapp = Flask(__name__)
#绑定配置文件
app.config.from_object(config)#可以让你先创建,再绑定
db.init_app(app)app.register_blueprint(qa_bp)
app.register_blueprint(auth_bp)if __name__ == '__main__':app.run()

User模型创建

先在navicat里新建数据库
在这里插入图片描述
在这里插入图片描述

#config.py
# 数据库的配置信息
HOSTNAME = '127.0.0.1'
PORT = '3306'
USERNAME = 'root'
PASSWORD = '123456'
DATABASE = 'zhiliaooa_course'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 datetimeclass UserModel(db.Model):__tablename__ = "user"id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(100), nullable=False)password = db.Column(db.String(100), nullable=False)email = db.Column(db.String(100), nullable=False)join_time = db.Column(db.DateTime, default=datetime.now)#app.py
from flask import Flask
import config
from exts import db
from models import UserModel
from blueprints.qa import bp as qa_bp
from blueprints.auth import bp as auth_bp
from flask_migrate import Migrateapp = Flask(__name__)
# 绑定配置文件
app.config.from_object(config)# 可以让你先创建,再绑定
db.init_app(app)migrate = Migrate(app, db)app.register_blueprint(qa_bp)
app.register_blueprint(auth_bp)if __name__ == '__main__':app.run()

然后运行三步
flask db init(只需第一次操作一下)
flask db migrate
flask db upgrade

然后数据库刷新下就可以看到
在这里插入图片描述

在这里插入图片描述

注册页面模型渲染

我们已经准备好了html文件和其静态样式,将其放入自己的文件内

其中本来只有红框标记的这几个
在这里插入图片描述
register.js是为了登录自己写的
base.html是为了减少代码量,能复用父组件base.html写的
(这部分可先跳过,后面会说)

#register.js
function bindEmailCaptchaClick(){$("#captcha-btn").click(function (event){// $this:代表的是当前按钮的jquery对象var $this = $(this);// 阻止默认的事件event.preventDefault();var email = $("input[name='email']").val();$.ajax({// http://127.0.0.1:500// /auth/captcha/email?email=xx@qq.comurl: "/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();
});
#base.html
<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="{{ url_for('static', filename='bootstrap/bootstrap.4.6.min.css') }}"><link rel="stylesheet" href="{{ url_for('static', filename='css/init.css') }}">{% block head %}{% endblock %}<title>{% block title %}{% endblock %}</title>
</head><body><nav class="navbar navbar-expand-lg navbar-light bg-light"><div class="container"><a class="navbar-brand" href="#">知了问答</a><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarSupportedContent"><ul class="navbar-nav mr-auto"><li class="nav-item active"><a class="nav-link" href="/">首页 <span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link" href="{{ url_for('qa.index') }}">发布问答</a></li><li class="nav-item ml-2"><form class="form-inline my-2 my-lg-0" method="GET" action="{{ url_for('qa.index') }}"><input class="form-control mr-sm-2" type="search" placeholder="关键字" aria-label="Search" name="q"><button class="btn btn-outline-success my-2 my-sm-0" type="submit">搜索</button></form></li></ul><ul class="navbar-nav">{% if user %}<li class="nav-item"><span class="nav-link">{{ user.username }}</span></li><li class="nav-item"><a class="nav-link" href="{{ url_for('auth.logout') }}">退出登录</a></li>{% else %}<li class="nav-item"><a class="nav-link" href="{{ url_for('auth.login') }}">登录</a></li><li class="nav-item"><a class="nav-link" href="{{ url_for('auth.register') }}">注册</a></li>{% endif %}</ul></div></div></nav><div class="container">{% block body %}{% endblock %}</div>
</body></html>

然后再auth.py里渲染前端页面

from flask import Blueprint,render_template# /auth,后面所有的路由都是以这个开头,比如/auth/login
bp=Blueprint("auth",__name__,url_prefix="/auth")@bp.route("/login")
def login():return "11"@bp.route("/register")
def register():return render_template("register.html")

在这里插入图片描述

Flask发送邮件功能实现

pip install flask_mail
然后准备好qq邮箱,其中一个这样子设置,是邮件的发送方
在这里插入图片描述
开启这个服务,我这里是之前已经开启过,如果没有开启的话开启
在这里插入图片描述

在这里插入图片描述
记住你的授权码
在这里插入图片描述
然后再config.py里进行邮箱配置

#邮箱配置
MAIL_SERVER = 'smtp.qq.com'
MAIL_PORT = 465
MAIL_USE_SSL = True
MAIL_USERNAME = '填入你刚刚操作的邮箱'
MAIL_PASSWORD = '填入你刚刚的授权码'
MAIL_DEFAULT_SENDER = '填入你刚刚操作的邮箱,和上面一致'

接下去进行如下操作

#exts.py
# flask-sqlalchemy
from flask_sqlalchemy import SQLAlchemy
from flask_mail import Maildb = SQLAlchemy()
mail = Mail()#app.py
from flask import Flask
import config
from exts import db,mail
from models import UserModel
from blueprints.qa import bp as qa_bp
from blueprints.auth import bp as auth_bp
from flask_migrate import Migrateapp = Flask(__name__)
# 绑定配置文件
app.config.from_object(config)# 可以让你先创建,再绑定
db.init_app(app)
mail.init_app(app)migrate = Migrate(app, db)app.register_blueprint(qa_bp)
app.register_blueprint(auth_bp)if __name__ == '__main__':app.run()

去auth.py测试一下

from flask import Blueprint,render_template
from exts import mail
from flask_mail import Message# /auth,后面所有的路由都是以这个开头,比如/auth/login
bp=Blueprint("auth",__name__,url_prefix="/auth")@bp.route("/login")
def login():return "11"@bp.route("/register")
def register():return render_template("register.html")@bp.route("mail/test")
def mail_test():message=Message(subject="邮箱测试",recipients=["填入你想发送人的邮箱,自己的也行"],body="这是一条测试邮件")mail.send(message)return "邮件发送成功"

在这里插入图片描述

发送邮箱验证码功能实现(1)

#auth.py
import random
import stringfrom flask import Blueprint,render_template
from exts import mail
from flask_mail import Message
from flask import request# /auth,后面所有的路由都是以这个开头,比如/auth/login
bp=Blueprint("auth",__name__,url_prefix="/auth")@bp.route("/login")
def login():return "11"@bp.route("/register")
def register():return render_template("register.html")@bp.route("/captcha/email")
def get_email_captcha():#/captcha/email/<email>#/captcha/email?email=123@qq.comemail=request.args.get("email")#4/6:随机数组、字母、数组和字母的组合source=string.digits*4captcha=random.sample(source,4)captcha="".join(captcha)print(captcha)return "success"@bp.route("mail/test")
def mail_test():message=Message(subject="邮箱测试",recipients=["123……@qq.com"],body="这是一条测试邮件")mail.send(message)return "邮件发送成功"

测试了一下验证码获取正常,继续完善

@bp.route("/captcha/email")
def get_email_captcha():#/captcha/email/<email>#/captcha/email?email=123@qq.comemail=request.args.get("email")#4/6:随机数组、字母、数组和字母的组合source=string.digits*4captcha=random.sample(source,4)captcha="".join(captcha)message = Message(subject="知了传课注册验证码", recipients=[email], body=f"您的验证码是:{captcha}")mail.send(message)return "success"

http://127.0.0.1:5000/auth/captcha/email?email=123……@qq.com网页中输入这段代码

在这里插入图片描述
现在有一个问题,如何验证用户提交的邮箱和验证码是否对应且正确
答:memcached/redis用数据库表的方式存储

发送邮箱验证码功能实现(2)

去model.py新建一个类

class EmailCaptchaModel(db.Model):__tablename__ = "email_captcha"id = db.Column(db.Integer, primary_key=True, autoincrement=True)email = db.Column(db.String(100), nullable=False)captcha = db.Column(db.String(100), nullable=False)

然后终端执行如下代码
在这里插入图片描述
数据库里可以看到新建了一个
在这里插入图片描述

#auth.py
import random
import stringfrom flask import Blueprint,render_template,jsonify
from exts import mail,db
from flask_mail import Message
from flask import request
from models import EmailCaptchaModel# /auth,后面所有的路由都是以这个开头,比如/auth/login
bp=Blueprint("auth",__name__,url_prefix="/auth")@bp.route("/login")
def login():return "11"@bp.route("/register")
def register():return render_template("register.html")@bp.route("/captcha/email")
def get_email_captcha():#/captcha/email/<email>#/captcha/email?email=123@qq.comemail=request.args.get("email")#4/6:随机数组、字母、数组和字母的组合source=string.digits*4captcha=random.sample(source,4)captcha="".join(captcha)message = Message(subject="知了传课注册验证码", recipients=[email], body=f"您的验证码是:{captcha}")mail.send(message)# 用数据库表的方式存储email_captcha=EmailCaptchaModel(email=email,captcha=captcha)db.session.add(email_captcha)db.session.commit()#RESTful API#{code:200/400/500,message:"",data:{}}return jsonify({"code":200,"message":"","data":None})@bp.route("mail/test")
def mail_test():message=Message(subject="邮箱测试",recipients=["1065088270@qq.com"],body="这是一条测试邮件")mail.send(message)return "邮件发送成功"

在这里插入图片描述

发送邮箱验证码功能实现(3)

#register.js
function bindEmailCaptchaClick(){$("#captcha-btn").click(function (event){// $this:代表的是当前按钮的jquery对象var $this = $(this);// 阻止默认的事件event.preventDefault();var email = $("input[name='email']").val();$.ajax({// http://127.0.0.1:500// /auth/captcha/email?email=xx@qq.comurl: "/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();
});

实现功能如下
在这里插入图片描述

发送邮箱验证码功能实现(4)

这部分是加入倒计时,也就是上面的内容,代码合在一块了

后端注册表单验证器实现

验证用户提交的邮箱和验证码是否对应且正确
pip install flask-wtf
在blueprints文件夹里新建forms.py

#forms.py
import wtforms
from wtforms.validators import Email,Length,EqualTo
from models import UserModel,EmailCaptchaModel
from exts import db# Form:主要就是用来验证前端提交的数据是否符合要求
class RegisterForm(wtforms.Form):email=wtforms.StringField(validators=[Email(message="邮箱格式不正确")])captcha=wtforms.StringField(validators=[Length(min=4,max=4,message="验证码长度必须为4位")])username=wtforms.StringField(validators=[Length(min=3,max=30,message="用户名长度必须在3-30之间")])password=wtforms.StringField(validators=[Length(min=6,max=30,message="密码长度必须在6-30之间")])password_confirm=wtforms.StringField(validators=[EqualTo("password",message="两次密码不一致")])# 自定义验证:#1、邮箱是否已经被注册def validate_email(self,field):email=field.datauser=UserModel.query.filter_by(email=email).first()if user:raise wtforms.ValidationError(message="邮箱已经被注册")# 2、验证码是否正确def validate_captcha(self,field):captcha=field.dataemail=self.email.datacaptcha_model=EmailCaptchaModel.query.filter_by(email=email).first()if not captcha_model:raise wtforms.ValidationError(message="邮箱或验证码错误!")# 最好是写一个脚本,自动多长时间清除# else:#     db.session.delete(captcha_model)#     db.session.commit()

后端注册功能完成

pip install email_validator
然后记得model.py里的password长度设置成200,因为用哈希加密后会超过原来设置的100,会报错(然后记得重新提交更新下数据库)

#auth.py
import random
import stringfrom flask import Blueprint,render_template,jsonify,redirect,url_for
from exts import mail,db
from flask_mail import Message
from flask import request
from models import EmailCaptchaModel
from werkzeug.security import generate_password_hashfrom .forms import RegisterForm
from models import UserModel# /auth,后面所有的路由都是以这个开头,比如/auth/login
bp=Blueprint("auth",__name__,url_prefix="/auth")@bp.route("/login")
def login():return "11"# GET:从服务器上获取数据
# POST:将客户端的数据向服务器提交
@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.datausername=form.username.datapassword=form.password.datauser=UserModel(email=email,username=username,password=generate_password_hash(password))db.session.add(user)db.session.commit()return redirect(url_for("auth.login"))else:print(form.errors)return redirect(url_for("auth.register"))@bp.route("/captcha/email")
def get_email_captcha():#/captcha/email/<email>#/captcha/email?email=123@qq.comemail=request.args.get("email")#4/6:随机数组、字母、数组和字母的组合source=string.digits*4captcha=random.sample(source,4)captcha="".join(captcha)message = Message(subject="知了传课注册验证码", recipients=[email], body=f"您的验证码是:{captcha}")mail.send(message)# 用数据库表的方式存储email_captcha=EmailCaptchaModel(email=email,captcha=captcha)db.session.add(email_captcha)db.session.commit()#RESTful API#{code:200/400/500,message:"",data:{}}return jsonify({"code":200,"message":"","data":None})@bp.route("mail/test")
def mail_test():message=Message(subject="邮箱测试",recipients=["1065088270@qq.com"],body="这是一条测试邮件")mail.send(message)return "邮件发送成功"

登录页面模板渲染完成

就是把login.html用base.html复用,然后渲染出来,给的资料里已经操作好了

#app.py
@bp.route("/login")
def login():return render_template("login.html")

登录功能后端实现

#forms.py新增一个类
class LoginForm(wtforms.Form):email=wtforms.StringField(validators=[Email(message="邮箱格式不正确")])password=wtforms.StringField(validators=[Length(min=6,max=30,message="密码长度必须在6-30之间")])
#auth.py

两个钩子函数


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/139171.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从0开始编写BP,自适应学习率的BP神经网络,不使用MATLAB工具箱,纯手写matlab代码,以BP分类为例...

与上篇文章不同&#xff0c;仔细读了上篇文章的小伙伴应该知道&#xff0c;BP神经网络是有一个学习率的&#xff0c;而这个学习率很大程度上决定着神经网络的效果。这里采用自适应学习率&#xff0c;实现纯手写BP神经网络。 编程时&#xff0c;激活函数选择Sigmoid函数&#xf…

倍福tnzip,tszip,tpzip文件的打开方式

文章目录 一. tnzip的打开方式二. tszip打开方法三. tpzip打开方法 一. tnzip的打开方式 打开项目&#xff1a;选择菜单栏 FILE&#xff0c;点击 Open Solution from Archive…&#xff0c;在弹出的 对话框中选择保存好的文件&#xff0c;单击打开。选择展开此项目的路径&…

MATLAB中sos2tf函数用法

目录 语法 说明 示例 二阶节系统的传递函数表示 sos2tf函数的功能是将数字滤波器的二阶节&#xff08;section&#xff09;数据转换为传递函数形式。 语法 [b,a] sos2tf(sos) [b,a] sos2tf(sos,g) 说明 [b, a] sos2tf(sos) 返回由 sos 描述的离散时间系统的传递函数系…

网络通信协议-HTTP、WebSocket、MQTT的比较与应用

在今天的数字化世界中&#xff0c;各种通信协议起着关键的作用&#xff0c;以确保信息的传递和交换。HTTP、WebSocket 和 MQTT 是三种常用的网络通信协议&#xff0c;它们各自适用于不同的应用场景。本文将比较这三种协议&#xff0c;并探讨它们的主要应用领域。 HTTP&#xff…

ARM +FPGA GPIB IP核实现

目前在数据发生其技术上居领先的是美国的 Tektronix 公司和 Agilent 公司。 Agilent 公司的台式脉冲 / 数据发生器家族的最高时钟频率达 3GHz &#xff08;定 时发生器&#xff09;&#xff0c;数据发生器 E81200 在通道数为 8CH 时数据速率为 660Mb/s, 即可以产…

一、初识 Elasticsearch:概念,安装,设置分词器

文章目录 01、初识 Elasticsearch正向索引和倒排索引索引MySQL与ES的概念映射安装ES分词器分词器的设置 01、初识 Elasticsearch 本次ES基于&#xff1a;7.12.1 版本 学习资源为&#xff1a;https://www.bilibili.com/video/BV1Gh411j7d6 什么是ES&#xff08;Elasticsearch&…

GitHub Action 通过SSH 自动部署到云服务器上

准备 正式开始之前&#xff0c;你需要掌握 GitHub Action 的基础语法&#xff1a; workflow &#xff08;工作流程&#xff09;&#xff1a;持续集成一次运行的过程&#xff0c;就是一个 workflow。name: 工作流的名称。on: 指定次工作流的触发器。push 表示只要有人将更改推…

【数据结构】栈

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈数据结构 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 栈-Stack 1. 什么是栈2. 栈的使用3.…

JAVA基础(JAVA SE)学习笔记(二)变量与运算符

前言 1. 学习视频&#xff1a; 尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 正文 第一阶段&#xff1a;Java基本语法 1. Java 语言概述 JAVA基础&#xff08;JAVA SE&#xff09;学习…

黑豹程序员-架构师学习路线图-百科:Maven

文章目录 1、什么是maven官网下载地址 2、发展历史3、Maven的伟大发明 1、什么是maven Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and…

ROS opencv 人脸识别

人脸识别需要在输入的图像中确定人脸&#xff08;如果存在&#xff09;的位置、大小和姿态&#xff0c;往往用于生物特征识别、视频监听、人机交互等应用中。2001年&#xff0c;Viola和Jones提出了基于Haar特征的级联分类器对象检测算法&#xff0c;并在2002年由Lienhart和Mayd…

使用 MRVA CodeQL 对开源项目进行大规模漏洞挖掘

1.什么是 MRVA? CodeQL相关的资料目前已经非常多了&#xff0c;但是大部分都集中在介绍ql语法以及基本使用上&#xff0c;更多关注的是对单个项目进行分析。那么如何批量进行漏洞挖掘呢&#xff1f;这里介绍下MRVA。 MRVA是multi-repository variant analysis 的缩写。其实是…