笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~
【论坛项目实战】 【python】Flask网页开发——论坛项目实战(完整代码) 【python】Flask网页开发——论坛项目实战(1.导航条实现) 【python】Flask网页开发——论坛项目实战(2.登录与注册) 【python】Flask网页开发——论坛项目实战(3.问答模块)
论坛项目实战(完整代码)
项目展示
页面展示
具体实现
1.导航条实现
2.登录与注册
3.问答模块
项目结构
1.创建项目
2.项目需要提前安装的包
3.项目结构
blueprints
forms.py
qa.py
user.py
models
models.py
static
bootstrap
bootstrap@4.6.min.css
jquery
jquery.3.6.min.js
js
register.js
templates
base.html
index.html
register.html
login.html
public_question.html
detail.html
app.py
config.py
decorators.py
exts.py
项目展示
页面展示
首页 发布问答 登录 注册 问答详情
具体实现
1.导航条实现
2.登录与注册
3.问答模块
项目结构
1.创建项目
2.项目需要提前安装的包
pymysql:Python操作数据库的驱动程序
Flask-SQLAlchemy:在Flask中使用ORM模型操作数据库
cryptography:对密码进行加密和解密
Flask-Migrate:将ORM模型的变更同步到数据库中
WTForms:用于处理表单的Python库
Flask-Mail : Flask 框架的一个扩展,用于在 Web 应用程序中发送电子邮件。
3.项目结构
blueprints
forms.py
import wtforms
from wtforms.validators import length, email, EqualTo
from models.models import EmailCaptchaModel, UserModel
class LoginForm(wtforms.Form):
email = wtforms.StringField(validators=[email()])
password = wtforms.StringField(validators=[length(min=6, max=20)])
class RegisterForm(wtforms.Form):
username = wtforms.StringField(validators=[length(min=3, max=20)])
email = wtforms.StringField(validators=[email()])
captcha = wtforms.StringField(validators=[length(min=4, max=4)])
password = wtforms.StringField(validators=[length(min=6, max=20)])
confirm_password = wtforms.StringField(validators=[EqualTo("password")])
def validate_captcha(self, field):
captcha = field.data
email = self.email.data
captcha_model = EmailCaptchaModel.query.filter_by(email=email).first()
if not captcha_model or captcha_model.captcha.lower() != captcha.lower():
raise wtforms.ValidationError("邮箱验证码错误!")
def validate_email(self, field):
email = field.data
user_model = UserModel.query.filter_by(email=email).first()
if user_model:
raise wtforms.ValidationError("邮箱已存在!")
class QuestionForm(wtforms.Form):
title = wtforms.StringField(validators=[length(min=3, max=200)])
content = wtforms.StringField(validators=[length(min=5)])
class AnswerForm(wtforms.Form):
content = wtforms.StringField(validators=[length(min=1)])
qa.py
from flask import Blueprint, render_template, request, g, redirect, url_for, flash
from decorators import login_required
from exts import db
from .forms import QuestionForm,AnswerForm
from models.models import QuestionModel, AnswerModel
from sqlalchemy import or_
bp = Blueprint("qa", __name__, url_prefix="/")
@bp.route("/")
def index():
questions = QuestionModel.query.order_by(db.text("-create_time")).all()
return render_template("index.html", questions=questions)
@bp.route("/question/public", methods=['GET', 'POST'])
@login_required # 装饰器
def public_question():
# 判断是否登录,没有登录,跳转到登录页面
if request.method == 'GET':
return render_template("public_question.html")
else:
form = QuestionForm(request.form)
if form.validate():
title = form.title.data
content = form.content.data
question = QuestionModel(title=title, content=content, author=g.user)
db.session.add(question)
db.session.commit()
return redirect("/")
else:
flash("标题或内容格式错误!")
return redirect(url_for("qa.public_question"))
@bp.route("/question/
def question_detail(question_id):
question = QuestionModel.query.get(question_id)
return render_template("detail.html", question=question)
@bp.route("/answer/
@login_required # 装饰器
def answer(question_id): # 注册
form = AnswerForm(request.form) # 存储前端表单的内容
if form.validate():
content = form.content.data
answer_model = AnswerModel(content=content, author=g.user, question_id=question_id)
db.session.add(answer_model)
db.session.commit()
return redirect(url_for("qa.question_detail", question_id=question_id))
else:
flash("请填写评论再提交!")
return redirect(url_for("qa.question_detail", question_id=question_id))
@bp.route("/search")
def search():
kword = request.args.get("kword")
questions = QuestionModel.query.filter(or_(QuestionModel.title.contains(kword),QuestionModel.content.contains(kword))).order_by(db.text("-create_time"))
return render_template("index.html",questions = questions)
user.py
from datetime import datetime
from flask import Blueprint, render_template, request, redirect, url_for, jsonify, session, flash
from exts import mail
from flask_mail import Message
from models.models import EmailCaptchaModel, UserModel
import string
import random
from exts import db
from .forms import RegisterForm, LoginForm
from werkzeug.security import generate_password_hash, check_password_hash
bp = Blueprint("user", __name__, url_prefix="/user")
@bp.route("/login", methods=['GET', 'POST'])
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 user and check_password_hash(user.password, password):
session['user_id'] = user.id
return redirect("/")
else:
flash("邮箱和密码不匹配!")
return redirect(url_for("user.login"))
else:
flash("格式错误!")
return redirect(url_for("user.login"))
@bp.route("/register", methods=
精彩文章
发表评论