效果展示:

登录

注册

主页面

项目结构

项目结构如下:

项目采用蓝图进行视图函数的管理,每个功能被放在一个小的app中。登录和注册功能放在了app_login文件夹中。

后端Python代码

app/login中的__init__.py创建了一个蓝图,内容如下:

# coding: utf-8# 作者(@Author): Messimeimei# 创建时间(@Created_time): 2023/1/8 23:19"""登录视图的蓝图"""from flask import Blueprintlogin = Blueprint("login", __name__)from . import view

models.py创建了一个数据模型User,对应数据库中的用户表,内容如下:

# coding: utf-8# 作者(@Author): Messimeimei# 创建时间(@Created_time): 2023/1/4 20:00"""登录需要的数据库模型(用户表)"""from werkzeug.security import generate_password_hash, check_password_hashfrom flask_login import UserMixinfrom app import dbclass User(UserMixin, db.Model):# 第一个参数指定字段类型,后面设置属性__tablename__ = 'users'id = db.Column(db.Integer, primary_key=True, autoincrement=True)count = db.Column(db.String(128), nullable=False)password = db.Column(db.String(128), nullable=False)def __init__(self, count, password):self.count = countself.password = passworddef set_password(self, password):self.password = generate_password_hash(password)def check_password(self, password):return check_password_hash(self.password, password)if __name__ == '__main__':user = User(count='0101', password=2021)db.session.add(user)db.session.commit()

viesw.py存放登录、注册的视图函数,内容如下:

# coding: utf-8# 作者(@Author): Messimeimei# 创建时间(@Created_time): 2023/1/6 11:39"""登录的视图函数"""from flask import request, render_template, redirect, url_for, flashfrom flask_login import login_required, login_userfrom . import loginfrom .models import Userfrom app import login_manager@login_manager.user_loaderdef load_user(user_id):# 创建用户加载回调函数,接受用户 ID 作为参数user = User.query.get(int(user_id))# 用 ID 作为 User 模型的主键查询对应的用户return user# 返回用户对象@login.route('/index', methods=['GET', 'POST'])@login_requireddef index():if request.method == "GET":return render_template('index.html')@login.route('/register', methods=['GET', 'POST'])def register():# 如果请求为postif request.method == 'POST':count = request.form.get('count')password = request.form.get('password')repassword = request.form.get('repassword')print(count, password)from app import dbif password == repassword:user = User(count, password)user.set_password(password)db.session.add(user)db.session.commit()return '注册成功'else:return '两次密码不一致'# 请求为getreturn render_template('register.html')@login.route('/', methods=['GET', 'POST'])@login.route('/login', methods=['GET', 'POST'])def login():if request.method == 'POST':count = request.form['count']password = request.form['password']print(password)if not count or not password:flash('Invalid input.')return redirect(url_for('login'))user = User.query.filter_by(count=count).first()if not user:flash("用户不存在")return redirect(url_for('login.login'))if count == user.count and user.check_password(password):login_user(user)# 登入用户flash('Login success.')print("登录成功")return redirect(url_for('login.index'))# 重定向到主页flash('Invalid username or password.')# 如果验证失败,显示错误消息return redirect(url_for('templates.login'))# 重定向回登录页面return render_template('login.html')

配置文件config.py

# coding: utf-8# 作者(@Author): Messimeimei# 创建时间(@Created_time): 2023/1/3 15:08"""各种配置类"""class BaseConfig(object):"""所有配置类的基类"""SECRET_KEY = "LOVE"DEBUG = TrueTESTING = FalseVISIT_TIME = 0# 网站访问次数# 数据库配置SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:自己的MySql密码@localhost/personalwebsite"SQLALCHEMY_TRACK_MODIFICATIONS = False# 是否追踪数据库的修改class ProductionConfig(BaseConfig):"""生产环境下的配置类"""DEBUG = Falseclass DevelopmentConfig(BaseConfig):"""开发模式下的配置类"""DEBUG = TrueTESTING = True

app/__init__.py

# coding: utf-8# 作者(@Author): Messimeimei# 创建时间(@Created_time): 2023/1/3 1:54"""构建app,注册蓝图"""from flask import Flaskfrom config import BaseConfigfrom flask_login import LoginManagerfrom flask_sqlalchemy import SQLAlchemylogin_manager = LoginManager()login_manager.session_protection = 'strong'login_manager.login_view = 'login'db = SQLAlchemy()def register_bp(app):"""注册蓝图:param app::return:"""from .app_login import login as login_blueprintapp.register_blueprint(login_blueprint)def database(app, db):"""初始化数据库:param app::return:"""db.init_app(app)db.create_all()db.session.commit()def create_app():my_app = Flask(__name__)with my_app.app_context():# app注册蓝图register_bp(my_app)# app加载配置my_app.config.from_object(BaseConfig)# 数据库管理对象database(my_app, db)# 用于登录验证login_manager.init_app(my_app)login_manager.login_view = 'login.login'return my_app

启动文件manager.py

# coding: utf-8# 作者(@Author): Messimeimei# 创建时间(@Created_time): 2023/1/3 13:50"""启动文件"""from app import create_appfrom flask import render_template, sessionapp = create_app()if __name__ == '__main__':app.run(debug=True)

前端代码(没有使用bootstrap)

html部分

登录login.html页面

登录页面

入口

账号密码

没有账号?注册

注册register.html页面

Title

注册

账号密码确认密码

已有账号?登录

主页面index.html

登录页面

css部分

login.css

body {margin: 0;padding: 0;font-family: sans-serif;background-size: cover;background: url(../images/bg.jpg) no-repeat fixed center 0;-webkit-background-size: cover;-o-background-size: cover;-moz-background-size: cover;-ms-background-size: cover;}.login-box {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);width: 400px;padding: 40px;background: rgba(16, 17, 19, 0.58);box-sizing: border-box;box-shadow: 0 10px 25px rgb(16, 17, 19);border-radius: 10px;}.login-box h2 {margin: 0 0 30px;padding: 0;text-align: center;color: #ffffff;}.login-box .login-field {position: relative;}.login-box .login-field input {width: 100%;padding: 10px 0;font-size: 16px;color: #ffffff;margin-bottom: 30px;border: none;border-bottom: 1px solid #ffffff;outline: none;background: transparent;}.login-box .login-field label {position: absolute;top: 0;left: 0;letter-spacing: 1px;padding: 10px 0;font-size: 16px;color: #ffffff;pointer-events: none;transition: .5s;}.login-box .login-field input:focus ~ label,.login-box .login-field input:valid ~ label {top: -23px;left: 0;color: aqua;font-size: 12px;}.login-box button {border: none;outline: none;color: #fff;background: #03a9f4;padding: 10px 20px;cursor: pointer;border-radius: 5px;}#myloginlabel{position: relative;background-color: rgb(3, 168, 243);border: 1px solid rgb(190, 225, 255);width: 100px;height: 30px;font-size: 12px;color: rgb(255, 255, 255);font-weight: 200;margin-top: 10px;text-align: center;border-radius: 20px;padding: 10px;}

index.css

body {margin: 0;padding: 0;font-family: sans-serif;background-size: cover;background: url(../images/index.jpg) no-repeat fixed center 0;-webkit-background-size: cover;-o-background-size: cover;-moz-background-size: cover;-ms-background-size: cover;}

js部分

register.js

function topggleForm() {var container = document.querySelector('.container');container.classList.toggle('active');}

两张背景图片(有需求自取,当然也可以换自己喜欢的,推荐一个网站https://pixabay.com/zh/)