Flask快速入门和问答项目源码
Flask基础入门
源码:
- gitee:我爱白米饭/Flask问答项目 - 码云
目录
- 1.安装环境
- 2.【debug、host、port】
- 3.【路由params和query】
- 4.【模板】
- 5.【静态文件】
- 6.【数据库连接】
- 6.1.安装模块
- 6.2.创建数据库并测试连接
- 6.3.创建数据表
- 6.4.ORM
- 增
- 删
- 改
- 查
- 6.5.ORM模型外键
- 6.6.映射和迁移
- 7.【问答平台项目】
- 7.1.环境准备
- 7.1.1 安装python环境
- 7.1.2.创建文件
- 7.1.3.绑定配置文件
- 7.2.创建数据库
- 7.3.创建蓝图
- 7.3.1.模板导航栏
- 7.3.2.用户注册和登录
- 🌟注册模板
- 🌟表单验证
- 🌟登录模板
- 🌟后端实现
- 7.3.3.用户问答和搜索
- 🌟问答和主页模板
- 🌟问答和主页视图
- 🌟问答详情和解答模板
- 🌟问答详情和解答视图
- 🌟搜索功能
- 🌟总视图代码
- 8.【总结】
正文内容如下:
1.安装环境
python - m venv .venv
pip install Flask
创建第一个实例
from flask import Flask# __name__:代表当前app.py这个模块
# 1.以后出现bug,他可以帮助我们快速定位
# 2.对于寻找模板文件,有一个相对路径
# 使用Flak类创建一个app对象
app = Flask(__name__)@app.route('/')
def hello_world(): # put application's code herereturn 'Hello World!'if __name__ == '__main__':app.run()
2.【debug、host、port】
from flask import Flask
# 使用Flak类创建一个app对象
app = Flask(__name__)@app.route('/')
def hello_world(): # put application's code herereturn 'Hello World!'if __name__ == '__main__':app.run(debug=True,host='0.0.0.0',port=8000) # 开启Debug模式、修改地址host、访问端口号port
3.【路由params和query】
from flask import Flask, request, render_templateapp = Flask(__name__)@app.route('/user/<username>')
def user(username):return f"用户名是{username}"# 年月日参数,http://127.0.0.1:5000/date/2025/05/16
@app.route('/date/<int:year>/<int:month>/<int:day>')
def date(year, month, day):return f"今天日期是{year}年{month}月{day}日"# /book/list?page=1&size=10
@app.route('/book/list')
def book_list():# arguments = {'page': 1, 'size': 10}# request.args:类字典类型page = request.args.get('page', 1, type=int)size = request.args.get('size', 10, type=int)return 'book_list/page=%s,size=%s' % (page, size)
4.【模板】
from flask import Flask, request, render_templateapp = Flask(__name__)
app.debug = True # 可选:显式设置 debug 模式@app.route('/detail/')
def BookDetail():return render_template("book_detail.html", title='Flask入门', author='李华',context={'title': 'Flask高级', 'author': '王明'})
目录结构,需要创建templates
├─static
├─templates
│ └─book_detail.html
├─app.py
5.【静态文件】
目录结构
├─static
│ └─css
│ └─js
│ └─img
├─templates
│ └─static_img.html
├─app.py
app.py
from flask import Flask, request, render_templateapp = Flask(__name__)
app.debug = True # 可选:显式设置 debug 模式@app.route('/img/')
def img():return render_template('static_img.html')if __name__ == '__main__':app.run(debug=True) # 开启Debug模式
static_img.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><img src="{{ url_for('static', filename='img/1.jpg') }}" alt="">
</body>
</html>
结果如下:
当然这是一个图片的案例,如果想引入css
、js
等或者其他文件内容的话,将filename='img/1.jpg'
的值替换一下就可以
其中,模板中也有过滤器的使用,可以自行网上查找,和django类似
6.【数据库连接】
6.1.安装模块
需要安装两个模块 flask_sqlalchemy
和pymysql
pip install flask_sqlalchemy
pip install pymysql
6.2.创建数据库并测试连接
创建数据库
create database flask_test default charset="utf8";
测试连接 ---- app.py
from flask import Flask, request, render_template
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)
app.debug = True # 可选:显式设置 debug 模式# 配置数据库
HOSTNAME = '127.0.0.1'
PORT = 3306
USERNAME = 'root'
PASSWORD = '123456'
DATABASE = 'flask_test'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)db = SQLAlchemy(app)
# 将数据库操作放在应用上下文中
with app.app_context():with db.engine.connect() as conn:print("连接成功")# 创建视图
@app.route('/')
def hello_world(): # put application's code herereturn 'Hello World!'if __name__ == '__main__':app.run(debug=True) # 开启Debug模式
注意:不要上下文缺失,with app.app_context():
,db.engine
需要应用上下文来读取配置(如数据库URI),但你的代码在应用启动前或上下文外调用了它
6.3.创建数据表
from flask import Flask, request, render_template
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)
app.debug = True # 可选:显式设置 debug 模式# 配置数据库
HOSTNAME = '127.0.0.1'
PORT = 3306
USERNAME = 'root'
PASSWORD = '123456'
DATABASE = 'flask_test'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD,HOSTNAME, PORT, DATABASE)db = SQLAlchemy(app)# 创建数据表
class User(db.Model):__tablename__ = 'user'id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(80), unique=True, nullable=False)password = db.Column(db.String(120), unique=True, nullable=False)with app.app_context():db.create_all()
6.4.ORM
数据
from flask import Flask, request, render_template
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)
app.debug = True # 可选:显式设置 debug 模式# 配置数据库
HOSTNAME = '127.0.0.1'
PORT = 3306
USERNAME = 'root'
PASSWORD = '123456'
DATABASE = 'flask_test'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD,HOSTNAME, PORT, DATABASE)db = SQLAlchemy(app)with app.app_context():db.create_all()# 创建数据表
class User(db.Model):__tablename__ = 'user'id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(80), unique=True, nullable=False)password = db.Column(db.String(120), unique=True, nullable=False)with app.app_context():db.create_all()if __name__ == '__main__':# app.run(debug=True,host='0.0.0.0',port=8000) # 开启Debug模式、修改地址host、访问端口号portapp.run(debug=True) # 开启Debug模式
增
@app.route('/user/add/')
def add_user():# 1.创建ORM对象user = User(username='admin', password='123456')# 2.添加到会话db.session.add(user)# 3.提交事务db.session.commit()return "添加成功"
删
@app.route('/user/delete/')
def delete_user():# 1.查询用户user = User.query.get(1)# 2.删除用户db.session.delete(user)# 3.提交事务db.session.commit()return "删除成功"
改
@app.route('/user/update/')
def update_user():# 1.查询用户user = User.query.get(1)# 2.更新用户信息user.password = '666666'# 3.提交事务db.session.commit()return "更新成功"
查
@app.route('/user/query/')
def query_user():# 1.查询所有用户,get单个查找user = User.query.get(1)print(user.id, user.username, user.password)# filter过滤查找,可以批量查找users = User.query.filter().all()for u in users:print(u.id, u.username, u.password)return "查询成功"
6.5.ORM模型外键
-
第一种方式
back_populates
class User(db.Model):__tablename__ = 'user'id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(80), unique=True, nullable=False)password = db.Column(db.String(120), unique=True, nullable=False)# 添加外键文章articles =db.relationship('Article', back_populates='author')class Article(db.Model):__tablename__ = 'article'id = db.Column(db.Integer, primary_key=True, autoincrement=True)title = db.Column(db.String(80), unique=True, nullable=False)content = db.Column(db.Text, unique=True, nullable=False)# 添加外键作者author_id = db.Column(db.Integer, db.ForeignKey('user.id'))# 添加关系属性 ,如果使用的是back_populates的话,那么在User类中也要添加articles属性author = db.relationship('User', back_populates='articles')
-
第二种
backref
class User(db.Model):__tablename__ = 'user'id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(80), unique=True, nullable=False)password = db.Column(db.String(120), unique=True, nullable=False)class Article(db.Model):__tablename__ = 'article'id = db.Column(db.Integer, primary_key=True, autoincrement=True)title = db.Column(db.String(200), unique=True, nullable=False)content = db.Column(db.Text, unique=True, nullable=False)# 添加外键作者author_id = db.Column(db.Integer, db.ForeignKey('user.id'))# 添加关系属性 ,如果使用的是back_populates的话,那么在User类中也要添加articles属性author = db.relationship('User', backref='articles')
文章的增
和查
@app.route('/article/add/')
def add_article():article = Article(title='Flask框架基础', content='教大家如何快速掌握Flask')article.author = User.query.get(1)# article2 = Article(title='Django框架基础',content='教大家如何快速掌握Django',author_id=1)article2 = Article(title='Django框架基础', content='教大家如何快速掌握Django', author_id=1)# 一次性添加多个数据使用add_all,传入的内容是一个列表db.session.add_all([article, article2])db.session.commit()return "添加成功"@app.route('/article/query/')
def query_article():# 通过user表种的userid获取所有的文章user = User.query.get(1)for a in user.articles:print(a.id, a.title, a.content, a.author.username)# 通过article表获取查询文章articles = Article.query.filter().all()for a in articles:print(a.id, a.title, a.content, a.author.username)return "查询成功"
6.6.映射和迁移
安装模块flask-migrate
pip install flask-migrate
之前使用的是
# 练习创建数据表使用
with app.app_context():db.create_all()
在开发过程中使用映射
from flask import Flask, request, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.debug = True # 可选:显式设置 debug 模式# 配置数据库
HOSTNAME = '127.0.0.1'
PORT = 3306
USERNAME = 'root'
PASSWORD = '123456'
DATABASE = 'flask_test'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD,HOSTNAME, PORT, DATABASE)db = SQLAlchemy(app)
migrate = Migrate(app, db) // 创建就行
命令使用,
-
第一步,生成环境,类似git的init
flask db init
会生成一个
migrations
文件├─migrations │ └─versions │ └─alembic.ini │ └─env.py │ └─README │ └─script.py.mako ├─static ├─templates
-
第二步,识别ORM模型的改变,生成迁移脚本
flask db migrate
-
第三步,运行迁移脚本,同步到数据库中
flask db upgrade
7.【问答平台项目】
7.1.环境准备
7.1.1 安装python环境
创建项目,其实就是一个文件夹的创建,进入文件夹后,需要配置下虚拟环境,和安装Flask
模块
python - m venv .venv
进入虚拟环境
.venv\Scripts\activate
安装依赖库
pip install Flask
# 数据库连接
pip install flask_sqlalchemy
pip install pymysql
# 数据库迁移和映射
pip install flask-migrate
# 邮箱模块
pip install flask-mail
# 表单验证
pip install flask-wtf
# 邮箱验证
pip install email_validator
pip install cryptography
7.1.2.创建文件
├─static # 静态资源
├─templates # 模板
├─app.py # 根
├─config.py # 配置文件
├─exts.py # 数据库配置信息
├─models.py # 数据库表配置
├─blueprints # 视图函数 & 后端请求
│ └─auth.py # 视图函数
│ └─qa.py # 视图函数
│ └─forms.py # 表单验证模块
├─decorators.py # 拓展:装饰器,拦截功能
7.1.3.绑定配置文件
-
config.py
配置# 配置数据库 HOSTNAME = '127.0.0.1' PORT = 3306 USERNAME = 'root' PASSWORD = '123456' DATABASE = 'flask_test' DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE) SQLALCHEMY_DATABASE_URI = DB_URI# 发送邮箱配置 # 授权码:ydevxpkfezjydddd ,授权码不是邮箱密码 MAIL_SERVER = 'smtp.qq.com' MAIL_PORT = 587 MAIL_USE_TLS = True MAIL_USERNAME = '你的邮箱' MAIL_PASSWORD = '授权码' MAIL_DEFAULT_SENDER = MAIL_USERNAME
使用qq邮箱作为服务器,打开设置
找到账号下的POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务
,开启服务,并获取授权码
-
exts.py
# 这个文件存在的意义就是为了解决循环引用的问题 from flask_sqlalchemy import SQLAlchemy # 导入邮箱实例模块 from flask_mail import Mail # 创建实例 db = SQLAlchemy() mail = Mail()
-
app.py
将配置的信息绑定
app.py
# 导入 flask模块 from flask import Flask # 导入 配置文件 import config # 导入 数据库实例和发送邮箱实例 from exts import db, mail # 导入 视图函数,并使用别名 from blueprints.auth import bp as auth_bp from blueprints.qa import bp as qa_bp # 导入 迁移和映射数据模块 from flask_migrate import Migrate# 实例Flask对象 app = Flask(__name__) app.debug = True # 可选:显式设置 debug 模式,在开发过程中开启即可,上线时删掉这行或者设置为False# 绑定config配置文件 app.config.from_object(config)# 初始化数据库db且绑定app db.init_app(app) # 初始化邮箱mail且绑定app mail.init_app(app)# 注册蓝图(相当于django中的视图) app.register_blueprint(auth_bp) app.register_blueprint(qa_bp)# 初始化数据库迁移(映射数据库) migrate = Migrate(app, db)if __name__ == '__main__':app.run()
7.2.创建数据库
使用命令行创建数据库,打开cmd
pymysql -u用户名 -p密码
创建utf8
编码的数据库
create database flask_test default charset="utf8";
进入models.py
创建数据库表,没有这个文件的话创建一下
# 导入已经实例化的对象
from exts import db
# 导入python内置的时间模块
from datetime import datetimeclass UserModel(db.Model):"""用户表"""__tablename__ = 'user'# id:主键primary_key=True,自增:autoincrement=Trueid = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(20), nullable=False)password = db.Column(db.String(200), nullable=False)email = db.Column(db.String(100), nullable=False, unique=True)join_time = db.Column(db.DateTime, default=datetime.now())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)class QuestionModel(db.Model):"""问答表"""__tablename__ = 'question'id = db.Column(db.Integer, primary_key=True, autoincrement=True)title = db.Column(db.String(100), nullable=False)content = db.Column(db.Text, nullable=False)create_time = db.Column(db.DateTime, default=datetime.now())author_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 外键# 可以通过questions取到UserModel的username,如:question.author.username author = db.relationship('UserModel', backref='questions') # 反向引用class AnswerModel(db.Model):"""评论/回答表"""__tablename__ = 'answer'id = db.Column(db.Integer, primary_key=True, autoincrement=True)content = db.Column(db.Text, nullable=False)create_time = db.Column(db.DateTime, default=datetime.now())question_id = db.Column(db.Integer, db.ForeignKey('question.id'))author_id = db.Column(db.Integer, db.ForeignKey('user.id'))question = db.relationship('QuestionModel', backref=db.backref('answers', order_by=create_time.desc()))author = db.relationship('UserModel', backref=db.backref('answers'))
在创建数据表的时候需要注意下外键的关系,外键的方向引用的用法,以及关联的数据表,当然,创建数据表还需要执行以下命令:
- 第二步,创建并初始化文件【执行一次即可】
flask db init
会在根目录下生成一个
migrations
的迁移文件├─migrations │ └─versions │ └─alembic.ini │ └─env.py │ └─README │ └─script.py.mako
- 第二步,识别ORM模型的改变,生成迁移脚本
flask db migrate
- 第三步,运行迁移脚本,同步到数据库中
flask db upgrade
注意:如果后续需要修改
models.py
中的内容,只需执行第二步
和第三步
即可,在Flask框架
中初始化文件只执行一次
7.3.创建蓝图
蓝图其实就是一个python程序包,命名为:blueprints
,在蓝图中创建两个视图文件(auth.py、qa.py
)和一个表单验证文件(forms.py
),目录结构为:
├─blueprints # 视图函数 & 后端请求
│ └─__init__.py
│ └─auth.py # 视图函数
│ └─qa.py # 视图函数
│ └─forms.py # 表单验证模块
7.3.1.模板导航栏
templates中创建base.html
,并写下以下内容,简单的导航栏就完成了,所有模板都是继承自这里
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>{% block title %}{% endblock %}</title><link rel="stylesheet" href="{{ url_for('static', filename='/bootstrap-3.4.1-dist/css/bootstrap.min.css') }}"><script type="text/javascript" src="{{ url_for('static', filename='/jquery/jquery-3.7.1.min.js') }}"></script><script type="text/javascript"src="{{ url_for('static', filename='/bootstrap-3.4.1-dist/js/bootstrap.min.js') }}"></script><style>body {padding-top: 20px;padding-bottom: 20px;}{% block css %}{% endblock %}</style>
</head>
<body>
<div class="container"><nav class="navbar navbar-default"><div class="container-fluid"><div class="navbar-header"><button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"aria-expanded="false" aria-controls="navbar"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand" href="/">Flask问答</a></div><div id="navbar" class="navbar-collapse collapse"><ul class="nav navbar-nav"><li class="active"><a href="/">首页</a></li><li><a href="{{ url_for('qa.public') }}">发布问答</a></li></ul><form class="navbar-form navbar-left" method="GET" action="{{ url_for('qa.search') }}"><div class="form-group"><input type="search" class="form-control" name="search" placeholder="Search"></div><button type="submit" class="btn btn-default">搜索</button></form><ul class="nav navbar-nav navbar-right">{% if user %}<li><a href="{{ url_for('auth.logout') }}">退出登录</a></li>{% else %}<li><a href="{{ url_for('auth.login') }}">登录</a></li><li><a href="{{ url_for('auth.register') }}">注册</a></li>{% endif %}</ul></div><!--/.nav-collapse --></div><!--/.container-fluid --></nav>{% block content %}{% endblock %}
</div>
</body>
{% block js %}{% endblock %}
</html>
7.3.2.用户注册和登录
auth.py
–用户注册,注册视图中有一个邮箱验证码的功能,在写用户注册的时候可以使用一个视图来验证邮箱验证码发送是否成功:
在发送之前还是需要环境准备
中准备下邮箱服务器的配置,在config
from flask import Blueprint, render_template, request, redirect, url_for, session, jsonify
from exts import mail
from flask_mail import Messagebp = Blueprint("auth", __name__, url_prefix="/auth")@bp.route("/mail/test/")
def send_mail():message = Message(subject="Hello", sender="服务器邮箱", recipients=["目的地邮箱"],body="This is a test email.")mail.send(message)return "Mail sent successfully!"
在实现注册功能的时候,需要准备下前端视图模板
🌟注册模板
register.html
{% extends "base.html" %}
{% block title %}注册{% endblock %}
{% block css %}.form-signin {max-width: 400px;padding: 15px;margin: 0 auto;}
{% endblock %}{% block content %}<div class="bs-example" data-example-id="panel-with-list-group"><!-- Default panel contents --><div class="panel-heading"><h3 style="text-align: center">注册</h3></div><div class="panel-body"><form class="form-signin" method="post"><div class="form-group"><label for="email">邮箱:</label><input type="email" class="form-control" name="email" id="email" placeholder="Email"></div><div class="form-group"><label for="captcha">验证码:</label><div class="input-group"><input type="text" id="captcha" name="captcha" class="form-control" placeholder="captcha"><span class="input-group-btn"><button class="btn btn-primary" id="get_captcha" type="button">获取验证码</button></span></div></div><div class="form-group"><label for="username">用户名:</label><input type="text" name="username" class="form-control" id="username" placeholder="username"></div><div class="form-group"><label for="password">密码:</label><input type="password" name="password" class="form-control" id="password" placeholder="password"></div><div class="form-group"><label for="password_confirm">确认密码:</label><input type="password" name="password_confirm" class="form-control" id="password_confirm"placeholder="password_confirm"></div><button type="submit" class="btn btn-primary">Submit</button></form></div></div>{% endblock %}
{% block js %}<script type="text/javascript">$(function () {bindEmailCaptchaClick()})function bindEmailCaptchaClick() {$("#get_captcha").click(function (event) {var $this = $(this)// 阻止表单提交event.preventDefault()const email = $("input[name='email']").val()$.ajax({url: "/auth/captcha/email?email=" + email, // 请求地址,method: "POST",success: function (result) {var code = result.codeif (code === 200) {var countdown = 60// 开始倒计时之前,就取消按钮的点击事件$this.off("click")var timer = setInterval(function () {$this.text(countdown + "s后重试")countdown--// 倒计时结束的时候执行if (countdown === 0) {clearInterval(timer)$this.text("获取验证码")bindEmailCaptchaClick()}}, 1000)}},fail: function (error) {console.log(error)}})})}</script>
{% endblock %}
🌟表单验证
forms.py
import wtforms
from wtforms.validators import Email, Length, EqualTo,InputRequired
from models import UserModel, EmailCaptchaModel
from exts import dbclass RegisterForm(wtforms.Form):email = wtforms.StringField(validators=[Email(message='邮箱格式错误')])captcha = wtforms.StringField(validators=[Length(min=4, max=4, message='验证码格式错误')])username = wtforms.StringField(validators=[Length(min=3, max=20, message='用户名格式错误')])password = wtforms.StringField(validators=[Length(min=6, max=20, message='密码格式错误')])password_confirm = wtforms.StringField(validators=[EqualTo('password', message='两次输入的密码不一致')])# 自定义验证:# 邮箱是否已经被注册def validate_email(self, field):email = field.datauser = UserModel.query.filter_by(email=email).first()if user:raise wtforms.ValidationError(message='邮箱已经被注册')# 验证码是否正确def validate_captcha(self, field):captcha = field.dataemail = self.email.datacaptcha_model = EmailCaptchaModel.query.filter_by(email=email, captcha=captcha).first()if not captcha_model:raise wtforms.ValidationError(message='邮箱验证码错误')class LoginForm(wtforms.Form):email = wtforms.StringField(validators=[Email(message='邮箱格式错误')])password = wtforms.StringField(validators=[Length(min=6, max=20, message='密码格式错误')])
🌟登录模板
用户登录模板login.html
{% extends "base.html" %}
{% block title %}注册{% endblock %}
{% block css %}.form-signin {max-width: 400px;padding: 15px;margin: 0 auto;}
{% endblock %}{% block content %}<div class="bs-example" data-example-id="panel-with-list-group"><!-- Default panel contents --><div class="panel-heading"><h3 style="text-align: center">登录</h3></div><div class="panel-body"><form class="form-signin" method="post"><div class="form-group"><label for="email">邮箱:</label><input type="email" class="form-control" name="email" id="email" placeholder="Email"></div><div class="form-group"><label for="password">密码:</label><input type="password" name="password" class="form-control" id="password"placeholder="password"></div><div class="checkbox"><label><input type="checkbox"> Check me out</label></div><button type="submit" class="btn btn-primary">Submit</button></form></div></div>
{% endblock %}
🌟后端实现
实现用户登录/注册
功能,auth.py
from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify
# 导入数据和邮箱实例对象
from exts import mail, db
# 导入邮箱信息发送模块
from flask_mail import Message
# python内置库
import string
import random
# 导入两个数据表
from models import EmailCaptchaModel, UserModel
# 表单验证模块
from .forms import RegisterForm, LoginForm
# 写入数据库中的密码加密
from werkzeug.security import generate_password_hash, check_password_hashbp = Blueprint("auth", __name__, url_prefix="/auth")# 只接受两种请求,分别是GET和POST
@bp.route("/login", methods=["GET", "POST"])
def login():if request.method == "GET":# 如果是GET请求,则是返回模板return render_template("login.html")else:form = LoginForm(request.form)if form.validate():# 获取到表单填写的内容,注意前端的input的name属性是和这里的form.name.data,中的name是一一对应的email = form.email.datapassword = form.password.datauser = UserModel.query.filter_by(email=email).first()if not user:print("用户不存在")# 重定向路由,实现连接跳转return redirect(url_for("auth.login")) if check_password_hash(user.password, password):session['user_id'] = user.idreturn redirect('/')# return "登录成功"else:print("密码错误")return redirect(url_for("auth.login"))else:print(form.errors)return redirect(url_for("auth.login"))@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.data# 将数据保存到数据库中user = UserModel(username=username, password=generate_password_hash(password), email=email)db.session.add(user)db.session.commit()return redirect(url_for("auth.login"))else:print(form.errors)return redirect(url_for("auth.register"))# http://127.0.0.1:5000/auth/captcha/email?email=2097969685@qq.com
@bp.route("/captcha/email", methods=["POST"])
def get_captcha():email = request.args.get("email")source = random.sample(string.digits * 4, 4)captcha = "".join(source)message = Message(subject="注册验证码", sender="2949666522@qq.com", recipients=[email],body=f"您的邮箱验证码为:{captcha},有效期1分钟。")mail.send(message)email_captcha = EmailCaptchaModel(email=email, captcha=captcha)db.session.add(email_captcha)db.session.commit()return jsonify({"code": 200, "message": "", "data": ""})@bp.route("/mail/test/")
def send_mail():message = Message(subject="Hello", sender="2949666522@qq.com", recipients=["2097969685@qq.com"],body="This is a test email.")mail.send(message)return "Mail sent successfully!"@bp.route("/logout")
def logout():session.clear()return redirect(url_for('auth.login'))
在app.py
中还需要添加
from models import UserModel@app.before_request
def my_before_request():user_id = session.get('user_id')if user_id:user = UserModel.query.get(user_id)setattr(g, 'user', user)else:setattr(g, 'user', None)@app.context_processor
def my_context_processor():return {'user': g.user}
效果:
7.3.3.用户问答和搜索
在写问答模块和搜索功能的时候,流程是:
问答模板----> 问答视图 ----> 权限设置(用户登录后才能访问问答页面) ----> 问答详情模板 ----> 问答详情视图 ----> 解答/评论模板 ----> 解答/评论视图 ----> 搜索功能实现
🌟问答和主页模板
index.html
{% extends 'base.html' %}{% block title %}首页{% endblock %}
{% block content %}<div class="bs-example" data-example-id="panel-with-list-group"><!-- Default panel contents --><div class="media-body"><div class="panel-heading"><h3 style="text-align: center">问答列表</h3></div><ul class="list-group">{% for question in questions %}<li class="list-group-item"><a href="{{ url_for('qa.detail', question_id=question.id) }}">{{ question.title }}</a><div class="media-body"><p class="media-heading">{{ question.content|truncate(length=100) }}</p></div><p class=" text-right"><span>{{ question.author.username }}     </span> {{ question.create_time }}</p></li>{% endfor %}</ul></div></div>
{% endblock %}
public.html
{% extends 'base.html' %}
{% block title %}发布问答{% endblock %}
{% block content %}<div class="panel panel-warning"><div class="panel-heading"><h3 class="text-center">发布问答</h3></div><div class="panel-body"><form class="form-signin" method="post"><div class="form-group"><label for="title">标题:</label><input type="text" class="form-control" name="title" id="title" placeholder="请输入标题"></div><div class="form-group"><label for="content">内容:</label><textarea name="content" rows="14" cols="60" class="form-control" id="content" placeholder="请输入内容"></textarea></div><div class="text-right"><button type="submit" class="btn btn-primary ">发布</button></div></form></div></div>
{% endblock %}
🌟问答和主页视图
这里有一个权限控制需要注意下,自定义权限,装饰器@login_required
存放在decorators.py
中
from functools import wraps
from flask import g, redirect, url_fordef login_required(func):# 保留func的信息@wraps(func)# *args, **kwargs是装饰器的参数,*args表示位置参数,**kwargs表示关键字参数def inner(*args, **kwargs):# 在func执行之前,先判断用户是否登录if g.user:return func(*args, **kwargs)else:return redirect(url_for('auth.login'))return inner
forms.py
import wtforms
from wtforms.validators import Email, Length, EqualTo,InputRequired
from models import UserModel, EmailCaptchaModelclass QuestionForm(wtforms.Form):title = wtforms.StringField(validators=[Length(min=3, max=100, message='标题长度在3-100之间')])content = wtforms.StringField(validators=[Length(min=5, message='内容至少需要5个字符')])class AnswerForm(wtforms.Form):content = wtforms.StringField(validators=[Length(min=5, message='内容至少需要5个字符')])question_id = wtforms.IntegerField(validators=[InputRequired(message='必须指明属于哪个问题')])
qa.py
from flask import Blueprint, render_template, request, redirect, url_for, g
from .forms import QuestionForm, AnswerForm
from models import QuestionModel, AnswerModel
from exts import db
# 导入自定义装饰器
from decorators import login_requiredbp = Blueprint("qa", __name__, url_prefix="/")@bp.route("/")
def index():questions = QuestionModel.query.order_by(QuestionModel.create_time.desc()).all()return render_template('index.html', questions=questions)@bp.route("/public", methods=['GET', 'POST'])
# 必须登录后才能访问
@login_required
def public():if request.method == 'POST':form = QuestionForm(request.form)if form.validate():title = form.title.datacontent = form.content.dataquestion = QuestionModel(title=title, content=content, author=g.user)db.session.add(question)db.session.commit()return redirect(url_for('qa.index'))else:print(form.errors)else:return render_template('public.html')
🌟问答详情和解答模板
detail.html
{% extends "base.html" %}
{% block title %}Flask-{{ question.title|truncate(10) }}{% endblock %}
{% block content %}<div class="jumbotron"><div><h2 class="text-center">{{ question.title }}</h2><p class="lead text-center small">作者:{{ question.author.username }}  时间:{{ question.create_time }}</p><hr><p class="text-center">{{ question.content }}</p></div><hr><div><h3>评论({{ question.answers|length }})</h3><form class="form-signin" method="post" action="{{ url_for('qa.answer') }}"><div class="form-group"><div class="input-group"><input type="text" class="form-control" name="content"/><input type="hidden" class="form-control" name="question_id" value="{{ question.id }}"/><span class="input-group-btn"><button class="btn btn-primary" type="submit">评论</button></span></div></div></form></div><hr><div class="bs-example" data-example-id="media-alignment">{% for answer in question.answers %}<div class="media"><div class="media-left"><img class="img-circle" data-src="holder.js/64x64" alt="64x64"src="{{ url_for('static', filename='img/1.jpg') }}" data-holder-rendered="true"style="width: 64px; height: 64px;"></div><div class="media-body "><h5 class="media-heading">{{ answer.author.username }}</h5><div class="row"><div class="col-md-10"><p>{{ answer.content }}</p></div><div class="col-md-2">{{ answer.create_time }}</div></div></div></div>{% endfor %}</div>
{% endblock %}
🌟问答详情和解答视图
qa.py
from flask import Blueprint, render_template, request, redirect, url_for, g
from .forms import QuestionForm, AnswerForm
from models import QuestionModel, AnswerModel
from exts import db
# 导入自定义装饰器
from decorators import login_requiredbp = Blueprint("qa", __name__, url_prefix="/")@bp.route('/detail/<question_id>')
def detail(question_id):question = QuestionModel.query.get(question_id)return render_template('detail.html', question=question)@bp.route('/answer/public', methods=["post"])
@login_required
def answer():form = AnswerForm(request.form)if form.validate():content = form.content.data# question_id = request.form.get('question_id')question_id = form.question_id.dataanswer = AnswerModel(content=content, question_id=question_id, author_id=g.user.id)db.session.add(answer)db.session.commit()return redirect(url_for('qa.detail', question_id=question_id))else:print(form.errors)return redirect(url_for('qa.detail', question_id=request.form.get('question_id')))
🌟搜索功能
搜索功能的视图是index.html
,但表单提交是在base.html
中们需要注意下表单提交的地址
base.html
<form class="navbar-form navbar-left" method="GET" action="{{ url_for('qa.search') }}"><div class="form-group"><input type="search" class="form-control" name="search" placeholder="Search"></div><button type="submit" class="btn btn-default">搜索</button>
</form>
qa.py
from flask import Blueprint, render_template, request, redirect, url_for, g
from .forms import QuestionForm, AnswerForm
from models import QuestionModel, AnswerModel
from exts import db
# 导入自定义装饰器
from decorators import login_requiredbp = Blueprint("qa", __name__, url_prefix="/")
@bp.route('/search')
def search():q= request.args.get('search')questions = QuestionModel.query.filter(QuestionModel.title.contains(q)).all()return render_template('index.html', questions=questions)
🌟总视图代码
qa.py
from flask import Blueprint, render_template, request, redirect, url_for, g
from .forms import QuestionForm, AnswerForm
from models import QuestionModel, AnswerModel
from exts import db
# 导入自定义装饰器
from decorators import login_requiredbp = Blueprint("qa", __name__, url_prefix="/")@bp.route("/")
def index():questions = QuestionModel.query.order_by(QuestionModel.create_time.desc()).all()return render_template('index.html', questions=questions)@bp.route("/public", methods=['GET', 'POST'])
@login_required
def public():if request.method == 'POST':form = QuestionForm(request.form)if form.validate():title = form.title.datacontent = form.content.dataquestion = QuestionModel(title=title, content=content, author=g.user)db.session.add(question)db.session.commit()return redirect(url_for('qa.index'))else:print(form.errors)else:return render_template('public.html')@bp.route('/detail/<question_id>')
def detail(question_id):question = QuestionModel.query.get(question_id)return render_template('detail.html', question=question)@bp.route('/answer/public', methods=["post"])
@login_required
def answer():form = AnswerForm(request.form)if form.validate():content = form.content.data# question_id = request.form.get('question_id')question_id = form.question_id.dataanswer = AnswerModel(content=content, question_id=question_id, author_id=g.user.id)db.session.add(answer)db.session.commit()return redirect(url_for('qa.detail', question_id=question_id))else:print(form.errors)return redirect(url_for('qa.detail', question_id=request.form.get('question_id')))@bp.route('/search')
def search():q= request.args.get('search')questions = QuestionModel.query.filter(QuestionModel.title.contains(q)).all()return render_template('index.html', questions=questions)
效果:
8.【总结】
博主是已经学习了很多Django知识,再来学习Flask知识的,所以了解起来很快,本次文档是跟着2025版-零基础玩转Python Flask框架-学完可就业_哔哩哔哩_bilibili这个视频学Flask基础知识并完成问答项目
博主觉得这个Flask课程完全是可以快速入门Flask框架的,而且视频博主也很贴心,有很多bug都是一起带着大家解决。
Flask完结👏👏🥳🥳
相关文章:
Flask快速入门和问答项目源码
Flask基础入门 源码: gitee:我爱白米饭/Flask问答项目 - 码云 目录 1.安装环境2.【debug、host、port】3.【路由params和query】4.【模板】5.【静态文件】6.【数据库连接】6.1.安装模块6.2.创建数据库并测试连接6.3.创建数据表6.4.ORM增删改查 6.5.ORM模…...
python创建flask项目
好的,我会为你提供一个使用 Flask、pg8000 和 Pandas 构建的后台基本框架,用于手机理财产品 App 的报表分析接口。这个框架将包含异常处理、模块化的结构以支持多人协作,以及交易分析和收益分析的示例接口。 项目结构: financial_report_ap…...
Flink 的窗口机制
🪟 1. 基于时间驱动的滚动时间窗口(Tumbling Time Window - Time-based) ✅ 定义: 每隔固定的时间周期开启一个新的窗口。窗口之间不重叠。 🕒 示例: DataStream<Tuple2<String, Integer>>…...
STM32 OTA 中断向量表重定向
在STM32的OTA(Over-the-Air)升级中,中断向量表重定向是关键技术需求,其核心原因在于STM32的硬件架构和固件运行机制。以下从原理、实现方式及必要性三个角度详细分析: 一、中断向量表的作用与默认机制 中断向量表的…...
先说爱的人为什么先离开
2025年5月19日,15~23℃,贼好的一天,无事发生 待办: 2024年税务申报 《高等数学2》取消考试资格学生名单 《物理[2]》取消考试资格名单 5月24日、25日监考报名 《高等数学2》备课 《物理[2]》备课 职称申报材料 教学技能大赛PPT 遇…...
OnlyOffice秘籍系列.6-表格保护功能详解-灵活设置单元格的权限
最近很多用户在咨询是否可以提供一个灵活控制表格权限的在线协同编辑表格,这里和大家分享如果用OnlyOffice在线表格实现。 OnlyOffice 是一款功能强大的在线协作办公套件,其表格工具(Spreadsheet Editor)提供了完善的数据保护机制,…...
LLM笔记(八)Transformer学习
文章目录 1. Transformer 整体架构2. 核心组件详解2.1. 输入部分 (Input Embedding & Positional Encoding)2.2. 注意力机制 (Attention Mechanism)2.2.1. Padding Mask (填充掩码)2.2.2. Sequence Mask (Look-ahead Mask / Subsequent Mask / Causal Mask) 2.3. Multi-Hea…...
Vue 3 中使用 md-editor-v3 的完整实例markdown文本
下面我将提供一个完整的 Vue 3 项目中使用 md-editor-v3 的 Markdown 编辑器实现,包含常用功能和最佳实践。 1. 基础实现 安装依赖 npm install md-editor-v3也可以是pnpm安装 pnpm install md-editor-v3基础编辑器组件 (BasicEditor.vue) <template> &l…...
OpenCV-图像分割
实验1 实验内容 上述代码通过使用OpenCV和Matplotlib库来执行以下操作: 读取名为’kt.jpg’的图像文件,并存储在变量img中。将图像img转换为灰度图像,将其存储在变量gray中。使用cv2.threshold函数对灰度图gray进行阈值化处理,…...
Vue-计算属性
计算属性 案例 输入姓、名, 全名称姓名 实现 插值语法 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>计算属性与监视</title><!-- 引入Vue --><script type&…...
16. 通用配置文件开发.py
16. 通用配置文件开发.py 一、配置文件架构设计 1.1 模块化结构规划 #mermaid-svg-Iuex47psGWeZj6XQ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Iuex47psGWeZj6XQ .error-icon{fill:#552222;}#mermaid-svg-Iu…...
Python训练营打卡 Day29
复习日:类的装饰器 知识点回顾 类的装饰器:餐厅升级计划 假设你是一家餐厅的老板,餐厅已经运营了一段时间,但你希望提升服务质量,比如在每道菜上增加一些特别的服务(比如日志记录、额外的装饰等)…...
解决 Tailwind CSS 代码冗余问题
解决 Tailwind CSS 代码冗余问题 Tailwind CSS 确实可能导致 HTML 类名过长和冗余的问题,以下是几种有效的解决方案: 1. 使用 apply 指令提取重复样式 /* 在CSS文件中 */ .btn {apply px-4 py-2 rounded-md font-medium; }.card {apply p-6 bg-white …...
【藏经阁】加密机服务完整解决方案,包含客户端+服务端
前言 你是否存在这样的苦恼,数据需要安全存储,但是每个系统大家自己写,很浪费时间。 encryption-local 一个离线版本的金融敏感信息加解密工具,用于数据库敏感信息存储。 离线版本的加解密好处是非常的方便。不过缺点也比较明显…...
互联网大厂Java求职面试:AI与大模型应用集成及云原生挑战
互联网大厂Java求职面试:AI与大模型应用集成及云原生挑战 面试场景设定 郑薪苦是一位具有搞笑风格但技术潜力巨大的程序员,正在接受一位严肃专业的技术总监面试。 第一轮提问 面试官:在我们公司的短视频平台中,需要处理千万级…...
ffmpeg -vf subtitles添加字幕绝对路径问题的解决方法
今天遇到奇怪的问题,老是报 Unable to parse option value Error applying option original_size to filter subtitles: Invalid argument 踩坑很长时间,记录下 因subtitles需要指定绝对路径, 注意点: 外面要用单引号 不能…...
JetBrains IDEA,Android Studio,WebStorm 等IDE 字体出现异常时解决方法
JetBrains IDEA,Android Studio,WebStorm 等IDE 中文字体出现异常,很怪的时候,通常需要设置字体回退才能解决。 需要在 Font 中将字体连写打开,并且设置字体回退为 Microsoft YaHei Ul 只有这样 IDEA 在没有中文字体的样式下,会将…...
鸿蒙AI开发:10-多模态大模型与原子化服务的集成
鸿蒙AI开发:10-多模态大模型与原子化服务的集成 在鸿蒙生态中,多模态大模型与原子化服务的集成是一个重要课题。本文将介绍如何在鸿蒙平台上进行多模态大模型与原子化服务的集成,以及相关的技术细节和实际案例。 鸿蒙AI开发概述 什么是鸿蒙AI…...
信奥赛CSP动态规划入门-最大子段和
针对**“最大子段和”**问题的详细分步解析与程序实现,通过动态规划将大问题分解为小问题: 一、问题拆解步骤 1. 明确问题定义 大问题:在数组[-2,1,-3,4,-1,2,1]中,找到连续子数组的和的最大值。 小问题:以每个位置i结尾的子数组能得到的最大和。 2. 状态定义 定义数组…...
Python爬虫实战:通过PyExecJS库实现逆向解密
1. 核心定义 1.1 PyExecJS 库 PyExecJS 是 Python 的第三方库,通过调用 JavaScript 运行时环境(如 Node.js、PhantomJS),实现 Python 与 JavaScript 的无缝交互。其核心功能包括: JavaScript 代码编译与执行跨语言函数调用与数据传递多引擎支持与自动环境检测1.2 字段加…...
网络安全深度解析:21种常见网站漏洞及防御指南
一、高危漏洞TOP 10 1. SQL注入(SQLi) 原理:通过构造恶意SQL语句突破系统过滤机制 典型场景: - 联合查询注入: union select 1,version(),3--+ - 布尔盲注:and (select substr(user(),1,1)=r) - 时间盲注:;if(now()=sysdate(),sleep(5),0)/ 防御方案: - 严格参数化查…...
web系统安全管理
一、概述 认证、授权是JavaWeb项目的核心部分。 二、相关概念 1、认证Authentication 认证,简单来说,就是确认用户身份的过程,确认“你是谁”(验证身份)。 2、授权(Authorization) 授权&…...
相机基础常识
相机基础常识 相机中颜色滤镜的作用🎨 1. **捕捉彩色图像**✅ 最常见的颜色滤镜阵列是 **拜耳滤镜(Bayer Filter)**: 🔍 2. **实现特定的图像效果或分析功能**✅ 常见的滤镜类型包括: 🛠️ 3. *…...
Python训练营打卡Day29
复习日:类的装饰器 知识点回顾 类的装饰器装饰器思想的进一步理解:外部修改、动态类方法的定义:内部定义和外部定义 1. 类的装饰器 类的装饰器是一种特殊的函数,用于修改或扩展类的行为。它们在类定义时被应用,类似于函…...
不同版本 Linux 系统账号操作指令 ——rtkit 账号删除、普通账号的创建 / 删除 / 权限修改超详细大全
不同版本 Linux 系统账号操作指令 ——rtkit 账号删除、普通账号的创建 / 删除 / 权限修改超详细大全 安全提醒 先备份:/etc/passwd 、/etc/shadow 、/etc/group 、/etc/sudoers 以及 Home 目录。系统账户慎删:rtkit 属于实时调度守护进程 RealtimeKit&…...
基于 Zookeeper 部署 Kafka 集群
文章目录 1、前期准备2、安装 JDK 83、搭建 Zookeeper 集群3.1、下载3.2、调整配置3.3、标记节点3.4、启动集群 4、搭建 Kafka 集群4.1、下载4.2、调整配置4.3、启动集群 1、前期准备 本次集群搭建使用:3 Zookeeper 3 Kafka,所以我在阿里云租了3台ECS用…...
Listener method could not be invoked with the incoming message
问题描述 生产者方代码: private void rollbackOrder(long orderId, CorrelationData correlationData) {rabbitTemplate.convertAndSend("order-rollback-exchange","rollback.order",new QuotaRollbackTO(orderId,null,null),correlationData…...
VueUse/Core:提升Vue开发效率的实用工具库
文章目录 引言什么是VueUse/Core?为什么选择VueUse/Core?核心功能详解1. 状态管理2. 元素操作3. 实用工具函数4. 浏览器API封装5. 传感器相关 实战示例:构建一个拖拽上传组件性能优化技巧与原生实现对比常见问题解答总结 引言 在现代前端开发…...
记录一次win11本地部署deepseek的过程
20250518 win11 docker安装部署 ollama安装 ragflow部署 deepseek部署 文章目录 1 部署Ollama下载安装ollama配置环境变量通过ollama下载模型deepseek-r1:7b 2 部署docker2.1 官网下载amd版本安装2.2 配置wsl2.3 Docker配置:位置代理镜像源 3 部署RAGFlow更换ragfl…...
PrimeVul论文解读-如何构建高质量漏洞标签与数据集
目录 1. 引入2. 现有漏洞识别方案的不足2.1 数据集中label不准2.2 数据重复2.3 测评标准不够好 3. 现有漏洞识别数据集分析3.1 关于现有数据集中label的准确率分析3.2 关于现有数据集中数据泄露( Data Leakage)情况分析 4. 漏洞识别测评5. PrimeVul数据集…...
现代生活健康养生新视角
在科技飞速发展的今天,我们的生活方式发生巨大转变,健康养生也需要新视角。从光线、声音等生活细节入手,能为健康管理开辟新路径。 光线与健康密切相关。早晨接触自然光线,可调节生物钟,提升血清素水平,…...
开启健康生活的多元养生之道
健康养生是一门值得终身学习的学问,在追求健康的道路上,除了常见方法,还有许多容易被忽视却同样重要的角度。掌握这些多元养生之道,能让我们的生活更健康、更有品质。 室内环境的健康不容忽视。定期清洁空调滤网,避…...
Flink 并行度的设置
在 Apache Flink 中,并行度(Parallelism) 是控制任务并发执行的核心参数之一。Flink 提供了 多个层级设置并行度的方式,优先级从高到低如下: 🧩 一、Flink 并行度的四个设置层级 层级描述设置方式Operator…...
抖音视频怎么去掉抖音号水印
你是不是经常遇到这样的烦恼?看到喜欢的抖音视频,想保存下来分享给朋友或二次创作,却被抖音号水印挡住了画面?别着急,今天教你几种超简单的方法,轻松去除水印,高清无水印视频一键保存࿰…...
类的加载过程详解
类的加载过程详解 Java类的加载过程分为加载(Loading)、链接(Linking) 和 初始化(Initialization) 三个阶段。其中链接又分为验证(Verification)、准备(Preparation&…...
运行:MSI Afterburner报错:应用程序无法启动并行配置不正确
从日志中可以看出,MSI Afterburner 运行时因缺少关键依赖组件(Microsoft.VC90.MFC)导致激活上下文生成失败。这是典型的 Visual C 运行时库缺失/版本不匹配 问题,与您提到的 for %1 in (%windir%\system32\*.dll) do regsvr32.exe…...
基于智能家居项目 ESP8266 WiFi 模块通信过程与使用方法详解
一、ESP8266 简介 ESP8266 是由乐鑫科技(Espressif)推出的一款低功耗、高集成度的 WiFi SoC 芯片。它内置 TCP/IP 协议栈,支持 STA(Station)、AP(Access Point)和 STA+AP 混合模式,可以独立作为主控 MCU 或配合其它主控(如 STM32、Arduino)通过串口通信使用。 常见…...
字节跳动开源通用图像定制模型DreamO,支持风格转换、换衣、身份定制、多条件组合等多种功能~
项目背景分析 图像定制是一个快速发展的领域,包括身份(ID)、风格、服装试穿(Try-On)等多种任务。现有研究表明,大规模生成模型在这些任务上表现出色,但大多数方法是任务特定的,难以推…...
Cursor:简单三步提高生成效率
第一步:结构化提示词——像写需求文档一样对话 常见误区:“做个知识管理模块,用SpringBoot。” 问题:AI会陷入迷茫——需要哪些字段?分页怎么做?异常处理是否需要? 正确写法: Note C…...
第二章 苍穹外卖
开发环境搭建_后端环境搭建_熟悉项目结构 constant:存储的是定义好的常量类 context:存储与上下文相关的 enumeration:存储枚举类 exception:存储一些异常 json:处理一些json转换的类 properties:存储一些配置类 …...
【上位机——WPF】命名空间
概述 XAML命名空间实际上是XML命名空间概念的扩展。指定XAML命名空间的技术依赖于XML命名空间语法、使用URL作为命名空间标识符的约定,使用前缀提供从同一标记源中引用多个命名空间的方法,诸如此类,XML命名空间的XAML定义中增加的主要概念是…...
当AI自我纠错:一个简单的“Wait“提示如何让模型思考更深、推理更强
原论文:s1: Simple test-time scaling 作者:Niklas Muennighoff, Zitong Yang, Weijia Shi等(斯坦福大学、华盛顿大学、Allen AI研究所、Contextual AI) 论文链接:arXiv:2501.19393 代码仓库:GitHub - simp…...
【聚类】 K-means
K-means 文章目录 K-means1. 算法介绍2. 公式及原理3. 伪代码1. 算法介绍 背景与目标 K-means 是最经典、最常用的原型聚类(prototype-based clustering)算法之一,由 Stuart Lloyd 于1957年提出,1982年被广泛推广。其核心目标是: 将给定的 n n n 个数据点划分为 K K K 个…...
matlab分段函数
在 MATLAB 中,定义分段函数可以使用 piecewise 函数或者条件语句(如 if、else)来实现。以下是两种常见方法的示例: 1. 使用 piecewise 函数(适用于符号函数) syms x f piecewise(x < 0, x^2, x > …...
《Vite 报错》ReferenceError: module is not defined in ES module scope
trip): [ReferenceError] module is not defined in ES module scope 解决方案 postcss.config.js 要改为 postcss.config.cjs,也就是 .cjs 后缀。 原因解析 原因解析 下图提示,packages.json 中的属性 type 设置为 module。所有*.js文件现在都被解释…...
基于matlab/simulink锂电池算法学习集合(SOC、SOH、BMS)
一、引言概述。 锂电池是目前在各个能源密集型行业中用途广泛,例如新能源汽车、电力微网、航空航天等。电池模型的建立对研究电池的特性、SOC(state-of-charge)估计、SOH(state-of-health)估计、BMS算法开发以及电池系统的快速实时仿真有重要的意义。 等效电路建模…...
10.8 LangChain三大模块深度实战:从模型交互到企业级Agent工具链全解析
LangChain Community 项目:Model I/O, Retrieval, Agent Tooling 关键词:LangChain Model I/O, 检索增强生成, Agent 工具链, 多路召回策略, 工具调用协议 1. Model I/O 模块:大模型交互标准化接口 Model I/O 是 LangChain 生态中连接大模型的核心模块,定义了统一的输入输…...
408考研逐题详解:2009年第16题
2009年第16题 某机器字长为 16 位,主存按字节编址,转移指令采用相对寻址,由两个字节组成,第一个字节为操作码字段,第二个字节为相对位移量字段。假定取指令时,每取一个字节 PC 自动加 1。若某转移指令所在…...
python打卡day29@浙大疏锦行
知识点回顾 类的装饰器装饰器思想的进一步理解:外部修改、动态类方法的定义:内部定义和外部定义 作业:复习类和函数的知识点,写下自己过去29天的学习心得,如对函数和类的理解,对python这门工具的理解等&…...
双紫擒龙紫紫红指标源码学习,2025升级版紫紫红指标公式-重点技术
VAR1:MA((LOWHIGHCLOSE)/3,5); VAR2:CLOSEHHV(C,4) AND REF(C,1)LLV(C,4); 双紫擒龙:REF(C,1)LLV(C,4) AND C>REF(C,2) OR REF(C,2)LLV(C,4) AND REF(C,1)<REF(C,3) AND REF(C,2)<REF(C,4) AND C>REF(C,1); VAR4:VAR1>REF(VAR1,1) AND REF(VAR1,1)<REF(VAR1,…...