知了问答 flask实战项目笔记(一)
1. 项目结构搭建
首先新建一个flask的项目,python环境选择先前使用过的环境,也可以选择新建环境
之后再新建一个config.py的文件,用来存放配置相关的
通过在app.py中进行绑定app.config.from_object(config)
第二件事情就是创建一个存放扩展文件/插件的地方,名为exts.py,
比如之前使用的flask-sqlalchemy
这样能够解决循环引用
创建models.py文件,用于存放模版对象
在app.py中配置db,将app对象传给db
蓝图buleprint
blueprint是用来进行视图函数模块化管理的,就是网络请求放在其他文件中,而不直接放在app.py文件中
blueprint需要在app.py文件中注册
auth.py
"""
@author: wtf
@file: auth.py
@time: 2024/5/8 16:36
@desc: Authorization related view controllers
"""
from flask import Blueprint
bp = Blueprint("auth", __name__, url_prefix="/auth") # url_prefix代表访问前缀
# 相当于127.0.0.1:5000/auth/login
@bp.route("/login")
def user_login():
pass
qa.py
"""
@author: wtf
@file: qa.py
@time: 2024/5/8 16:39
@desc: View controllers related to Q&A
"""
from flask import Blueprint
bp = Blueprint("qa", __name__, url_prefix="/")
bp.route("/")
def index():
pass
app.py中绑定蓝图
# 注册blueprint
app.register_blueprint(qa_bp)
app.register_blueprint(auth_bp)
2.User模型创建
创建User模型
class 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, unique=True)
join_time = db.Column(db.DateTime, default=datetime.now) # 默认值为当前存储时间,传入的是一个函数,所以不用加()
配置config.py文件
"""
@author: wtf
@file: config.py
@time: 2024/5/8 16:09
"""
# 配置数据库信息
HOSTNAME = "127.0.0.1"
PORT = 3306
USERNAME = "root"
PASSWORD = 1234
DATABASE = "zhiliaooa"
DB_URI = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8'
SQLALCHEMY_DATABASE_URI = DB_URI # 这句不能少,少了migrate时会报错
app.py文件内容为:
"""
@author: wtf
@file: config.py
@time: 2024/5/8 16:06
"""
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 Migrate
app = Flask(__name__)
# 绑定配置文件
app.config.from_object(config)
migrate = Migrate(app, db)
# 配置db
db.init_app(app)
# 注册blueprint
app.register_blueprint(qa_bp)
app.register_blueprint(auth_bp)
if __name__ == '__main__':
app.run()
然后使用命令行写入数据库
flask db init
flask db imgrate
flask db upgrade
最后生成数据库
3.html页面改造
通过继承父类模版,能够使得子类模版的内容较少,且美观
提取到base.html
记得将资源路径给成jinjia2模式下的写法<link rel="stylesheet" href="{{ url_for('static', filename="css/init.css") }}">
<!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="#">发布问答</a>
</li>
<li class="nav-item ml-2">
<form class="form-inline my-2 my-lg-0" method="GET" action="#">
<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">
<li class="nav-item">
<a class="nav-link" href="#">登录</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">注册</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
{% block body %}{% endblock %}
</div>
</body>
</html>
register.html
{% extends "base.html" %}
{% block title %}
知了传课-注册
{% endblock %}
{% block body %}
<div class="container">
<div class="row mt-4">
<div class="col"></div>
<div class="col">
<form method="POST" action="#">
<div class="form-group">
<label for="exampleInputEmail1">邮箱</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" name="email">
<small id="emailHelp" class="form-text text-muted">我们不会把邮箱用于其他用户</small>
</div>
<div class="form-group">
<label for="exampleInputEmail1">验证码</label>
<div class="input-group">
<input type="text" class="form-control" name="captcha">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button" id="captcha-btn">获取验证码</button>
</div>
</div>
</div>
<div class="form-group">
<label for="exampleInputEmail1">用户名</label>
<input type="text" class="form-control" name="username">
</div>
<div class="form-group">
<label for="exampleInputPassword1">密码</label>
<input type="password" class="form-control" id="exampleInputPassword1" name="password">
</div>
<div class="form-group">
<label for="exampleInputPassword1">确认密码</label>
<input type="password" class="form-control" name="password_confirm">
</div>
<button type="submit" class="btn btn-primary btn-block">立即注册</button>
</form>
</div>
<div class="col"></div>
</div>
</div>
{% endblock %}