概述
1. 留言板功能构想
功能
用户注册 ,检测用户名是否重复,二次密码确认
用户登录,密码错误提示
头像上传
用户留言,主页展示留言,留言时间,留言者
redis 存储session信息
mysql存储用户信息,留言信息
2. 创建项目
项目目录结构
mainapp是flask主要目录,
static静态资源存放css文件,以及photos存放网页图片以及用户上传图片
templates存放网页文件
__init__.py 加载配置,以及存放视图处理函数
models使用sqlalchemy实现数据库功能
utils常用工具库
manage以脚本的方式启动flask
settings存放 flask的一些配置
.gitignore/README.md/reqirements.txt 用于上传github
3. 准备工作
3.1settings文件
from redis import Redis
from datetime import timedelta
class Dev(object):
# 如果不更改ENV(开发环境) 默认是production产品模式
# 生产模式
ENV = 'developement'
# session密钥
SECRET_KEY = 'ElricTian'
# 静态文件缓存时间
# 这里是为了在更换头像的时候能刷新 否则静态文件不过期
SEND_FILE_MAX_AGE_DEFAULT = timedelta(seconds=1)
# 配置session 以及 redis
"""Redis默认的配置会生成db0~db15共16个db,
切分出16个db的一个作用是方便不同项目使用不同的db,
防止的数据混淆,也为了方便数据查看"""
CONFIG = {
'host': '127.0.0.1',
'port': 6379,
'db': 15
}
SESSION_TYPE = 'redis'
SESSION_REDIS = Redis(**CONFIG)
# 配置sqlalchemy
# 连接数据库
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123456@127.0.0.1:3306/message_board'
# 可扩展
SQLALCHEMY_TRACK_MODIFICATION = True
# 回收资源时自动提交事务
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
# 显示调试SQL
SQLALCHEMY_ECHO = True
3.2配置数据库
我是直接使用Navicat创建的
存储留言信息的表,设置了timestamp,直接自动获取留言时间
CREATE TABLE `message` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL COMMENT '用户名',
`content` varchar(255) NOT NULL COMMENT '留言内容',
`time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '留言时间',
PRIMARY KEY (`id`)
) ;
存储头像的方法我一开始是打算用二进制存进数据库里,
使用base64是主流的方法,但是无奈能转换成base64但是没办法在前端页面显示(需要用到js)
后面就直接存储图片的路径了 在从静态资源文件里加载
password一般使用md5加密钥加密 这里没有使用
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码',
`img` varchar(255) DEFAULT NULL COMMENT '头像',
`hobby` varchar(255) DEFAULT NULL,
`age` int DEFAULT NULL,
PRIMARY KEY (`id`)
);
3.3models下的__init__.py 创建数据库对象 以及模型对应关系
from flask_sqlalchemy import SQLAlchemy
# 创建数据库对象
db = SQLAlchemy()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(255))
password = db.Column(db.String(255))
img = db.Column(db.String(255))
class Message(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(255))
content = db.Column(db.String(255))
time = db.Column(db.TIMESTAMP,
nullable=False,
comment='更新时间戳',
server_default=db.text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
3.4mainapp下的__init__.py文件
3.4.1所需要的包
import settings
# flask相关功能包
from flask import Flask
from flask_session import Session
from flask import request, render_template, redirect, url_for, session
# 数据库操作
from models import db, Message
from models.UserDB import UserDB
from models.MessageDB import MessageDB
3.4.2初始化
# 创建app对象 加载配置
app = Flask(__name__)
app.config.from_object(settings.Dev())
# 创建Session对象
# 这里的session不是原生态flaks的session 而是flask_session中的session|
# 命名为sessions是为了不和session冲突
sessions = Session()
sessions.init_app(app)
# 初始化数据库
db.init_app(app)
# 创建表对象
user_db = UserDB()
message_db = MessageDB()
3.5以脚本的方式启动flask manage.py文件
from mainapp import app
from flask_script import Manager
manger = Manager()
if __name__ == '__main__':
# 以脚本的方式启动flask应用服务
manager = Manager(app)
manager.run()
4.数据库操作
4.1用户操作
modesl下user_db.py文件
from models import User, db
class UserDB(object):
@staticmethod
def search_user(username, password):
# 检查用户登录
results = User.query.filter(User.name == username, User.password == password)
if results:
for result in results:
message = result.name
return message
else:
return None
@staticmethod
def rechecking(username):
# 检查是否注册过
results = User.query.filter(User.name == username).all()
if results:
return 1
else:
return None
@staticmethod
def reg_user(name, password):
# 注册
user = User()
user.name = name
user.password = password
db.session.add(user)
db.session.commit()
return 1
@staticmethod
def save_img(username, img_path):
# 存储图片路径
user = User.query.filter(User.name == username).first()
user.img = img_path
db.session.commit()
return 1
@staticmethod
def show_info(username):
# 个人信息关联查询
sql = "SELECT user.img, user.hobby, user.age, message.content, message.time "
"FROM user "
"LEFT JOIN message "
"ON user.name=message.name WHERE user.name='%s'" % username
# 原生态sql语句
results = db.session.execute(sql)
return list(results)
4.2留言信息操作
modesl下message_db.py文件
from models import Message, db
class MessageDB(object):
@staticmethod
def save_message(name, content):
message = Message()
message.name = name
message.content = content
db.session.add(message)
db.session.commit()
return 1
5.开始编写视图函数
5.1用户注册
均使用local()传入渲染网页参数
@app.route('/register', methods=['GET', 'POST'])
def user_register():
# 用户注册
if request.method == 'POST':
name = request.form.get('Name')
password = request.form.get('Password')
confirm_password = request.form.get('Confirm Password')
print(name, password)
if all((name, password, confirm_password)):
if password != confirm_password:
tips = '请输入相同的密码'
else:
# 查找是否有此用户
re_result = user_db.rechecking(name)
if not re_result:
reg_result = user_db.reg_user(name, password)
if reg_result == 1:
# 注册成功自动跳转
return redirect(url_for('login'))
elif re_result == 1:
message = '该用户已存在'
else:
tips = '请输入注册完整的信息'
return render_template('register.html', **locals())
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<h2>注册</h2>
<form action="/register" method="post">
用户名<br><input name="Name"><br>
密码<br><input type="password" name="Password" ><br>
确认密码<br><input type="password" name="Confirm Password" ><br>
<button>注册</button>
</form>
<h4>{{ tips }}</h4>
</body>
</html>
5.2用户登录
登录的时候会把用户名加入session中,这样不管在哪个页面中都可以获取用户名
@app.route('/login', methods=['GET', 'POST'])
def login():
register = url_for('user_register')
if request.method == 'POST':
# 读取登录用户信息
name = request.form.get('name')
password = request.form.get('password')
user = user_db.search_user(name, password)
if all((name, password)):
if not user:
tips = "请检查用户名或密码是否正确,或前往注册"
else:
# 将用户信息加入session
session['login_user'] = user
# 自动跳转返回主页
return redirect(url_for('index'))
else:
tips = '请勿留空白'
return render_template('login.html', **locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<h3>用户登录</h3>
<form action="/login" method="post">
用户名:<input name="name" size="20"><br>
密 码:<input name="password" type="password" size="20"><br>
<button>登录</button>
</form>
{{ tips }}<br>
<a href="{{ register }}">注册</a>
</body>
</html>
5.3退出登录
@app.route('/logout')
def logout():
del session['login_user']
# 退出登录返回主页
return redirect(url_for('index'))
5.4主页
@app.route('/', methods=['GET', 'POST'])
def index():
# 判断是否登录
if not session.get('login_user'):
return """请先登录,正在跳转...<meta http-equiv="refresh" content="2;url= %s"/>
""" % url_for('login')
# 当前用户
user = session.get('login_user')
if request.method == 'POST':
content = request.form.get('Content')
if len(content) == 0:
tips = '请勿输入空的留言'
else:
result = message_db.save_message(name=user, content=content)
if result == 1:
tips = '留言成功'
# 显示所有留言信息
message_list = Message.query.all()
return render_template('index.html', **locals())
5.5个人中心
@app.route('/user')
def user_index():
user = session.get('login_user')
result = user_db.show_info(user)
hobby = result[0].hobby
age = result[0].age
img_path = result[0].img
message_list = result
return render_template('user.html', **locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>个人主页</title>
<style>
div{
width: 200px;
height: 200px;
}
div img{width:100%}
</style>
</head>
<body style="background-color: #537cca;">
<div>
<img src="/static/photos/{{ img_path }}" alt="" >
</div>
<a href="/upload_head">
<button>修改头像</button><br>
</a><br>
<a href="/">
<button>前往主页</button><br>
</a>
<h2>用户名:{{ user }}</h2>
<h3>爱好:{{ hobby }}</h3><h3>年龄:{{ age }}</h3>
<h3>
留言记录:
{% for message in message_list %}
<li>内容:{{ message.content }}</li>
<li>留言时间:{{ message.time }}</li>
<br>
{% endfor %}
</h3>
</body>
</html>
5.6上传头像
@app.route('/upload_head', methods=['GET', 'POST'])
def upload_file():
# 上传头像到本地
if request.method == 'POST':
# 上传图片到静态资源里
file = request.files['file']
path = r'C:UsersAdministratorDesktopmessage_boardmainappstaticphotosuser_'
user = session.get('login_user')
filename = user + '.jpg'
file.save(path + filename)
# 存入路径到数据中
img_path = 'user_' + filename
result = user_db.save_img(user, img_path)
return """上传成功,正在跳转...<meta http-equiv="refresh" content="2;url= %s"/> """ % url_for('user_index')
return render_template('upload_head.html', **locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传头像</title>
</head>
<body>
<h1>上传头像</h1>
<form action = "" method = "post" enctype=multipart/form-data>
<input type = "file" name = "file" accept=" .jpg, .jpeg, .png, .gif "><br><br>
<input type = "submit" value = 上传>
</form>
</body>
</html>
6.总结
github: git@github.com:ElricTian/flask-messageboard.git
这个项目较简单,花费了不到两天时间,
由于没有学习前端,很多地方都是简单的样式和功能,
如果对应上前端界面会有更多问题等着我去解决,
在不断的学习中还可以对某些功能拓展,
比如实现翻页功能,倒序升序显示,点赞等,
如果有什么建议或者不懂的地方,欢迎留言~
7.更新
更新了css和网页文件
网站效果图如下
最后
以上就是忧虑大炮为你收集整理的使用Flask开发留言板1. 留言板功能构想2. 创建项目3. 准备工作4.数据库操作5.开始编写视图函数6.总结7.更新的全部内容,希望文章能够帮你解决使用Flask开发留言板1. 留言板功能构想2. 创建项目3. 准备工作4.数据库操作5.开始编写视图函数6.总结7.更新所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复