1、创建初期目录
项目环境依赖库如下:
创建项目包含文件
主程序文件bbs.py
# -*- encoding: utf-8 -*-
"""
@File : bbs.py
@Time : 2020/5/11 9:46
@Author : chen
"""
# 项目主文件,启动入口
# 前台 front 管理前端界面的逻辑
# 后台 cms 管理后端的操作
# 公有的文件 common
from flask import Flask
import config # 配置文件库
from exts import db # 第三方库导入db
from apps.cms.views import cms_bp # 导入后端蓝图文件
from apps.front.views import front_bp # 导入前端蓝图文件
app = Flask(__name__)
app.config.from_object(config) # 添加配置
db.init_app(app) # 绑定app
app.register_blueprint(cms_bp) # 后端蓝图文件注册
app.register_blueprint(front_bp) # 前端蓝图文件注册
if __name__ == '__main__':
app.run(debug=True, port=9999)
配置文件:config.py:数据库连接固定写法
# -*- encoding: utf-8 -*-
"""
@File : config.py
@Time : 2020/5/11 10:08
@Author : chen
"""
# 127.0.0.1
HOSTNAME = "localhost"
DATABASE = "demo_bbs"
PORT = 3306
USERNAME = "root"
PASSWORD = "root"
DB_URL = 'mysql+mysqlconnector://{}:{}@{}:{}/{}'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URL # 数据库连接成功
# FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.
# Set it to True or False to suppress this warning.'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
# 这里是为了解决上面的警告
SQLALCHEMY_TRACK_MODIFICATIONS = False
第三方引用文件:exts.py
# 第三方引用文件,防止互相引用报错
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
映射模型到数据库:manage.py
# -*- encoding: utf-8 -*-
"""
@File : manage.py
@Time : 2020/5/10 17:36
@Author : chen
"""
from flask_script import Manager
from bbs import app # 需要将当前文件夹设置为当前根目录,才不会报错
from flask_migrate import Migrate, MigrateCommand
from exts import db
# 导入模型 才能映射到数据库 导入后端的模型
from apps.cms.models import CMS_User
manage = Manager(app)
Migrate(app, db)
manage.add_command('db', MigrateCommand)
# 命令行添加后端用户
@manage.option('-u', '--username', dest='username')
@manage.option('-p', '--password', dest='password')
@manage.option('-e', '--email', dest='email')
def create_cms_user(username, password, email):
user = CMS_User(username=username, password=password, email=email)
# 添加映射到数据库,提交至数据库
db.session.add(user)
db.session.commit()
print("cms后端用户添加成功")
后台开发文件包:apps/cms
后台视图文件:apps/cms/views.py
# -*- encoding: utf-8 -*-
"""
@File : views.py
@Time : 2020/5/11 9:59
@Author : chen
"""
# 蓝图文件:实现模块化应用,应用可以分解成一系列的蓝图 后端的类视图函数写在这个文件
from flask import Blueprint
cms_bp = Blueprint("cms", __name__, url_prefix='/cms/') # URL前缀url_prefix
@cms_bp.route("/")
def index():
return "cms index:后端类视图文件"
后台模型文件:apps/cms/models.py
# -*- encoding: utf-8 -*-
"""
@File : models.py
@Time : 2020/5/11 10:00
@Author : chen
"""
# 定义后端用户模型
from exts import db
from datetime import datetime
class CMS_User(db.Model):
__tablename__ = 'cms_user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 主键 自增
username = db.Column(db.String(150), nullable=False) # 非空
password = db.Column(db.String(150), nullable=False)
email = db.Column(db.String(50), nullable=False, unique=True) # 非空、唯一
join_time = db.Column(db.DateTime, default=datetime.now) # 默认当前时间
前台开发文件包:apps/front
前台视图文件:apps/front/views.py
# -*- encoding: utf-8 -*-
"""
@File : views.py
@Time : 2020/5/11 9:59
@Author : chen
"""
# 前端的蓝图文件 类视图函数写在这里
from flask import Blueprint
front_bp = Blueprint("front_bp", __name__) # 前端不用前缀,直接在首页显示
@front_bp.route("/")
def index():
return "front index:前端的首页"
此时的密码是明文状态,现在针对密码加密进行修改
2、密码加密
后台模型文件:apps/cms/models.py
# 定义后端用户模型
from exts import db
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash # 导入密码加密解密方法的库
class CMS_User(db.Model):
__tablename__ = 'cms_user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 主键 自增
username = db.Column(db.String(150), nullable=False) # 非空
# password = db.Column(db.String(150), nullable=False)
_password = db.Column(db.String(150), nullable=False) # 密码加密操作修改字段
email = db.Column(db.String(50), nullable=False, unique=True) # 非空、唯一
join_time = db.Column(db.DateTime, default=datetime.now) # 默认当前时间
# 修改密码加密操作中的字段,在manage.py映射数据库时候,使用字段还是保持相同
def __init__(self, username, password, email):
self.username = username
self.password = password # 调用该方法 返回下面的self._password数值,
self.email = email
# 密码加密操作
@property
def password(self): # 密码取值
return self._password
@password.setter # 密码加密 xxx.setter需要和上面的方法名称相同
def password(self, raw_password):
self._password = generate_password_hash(raw_password)
3、登录前端界面制作
登录界面的模板参考:
bootstrap登录模板html文件
bootstrap登录模板css文件
前端静态资源文件:cms_login.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<meta name="description" content="">
<meta name="author" content="">
<!-- <link rel="icon" href="../../favicon.ico">-->
<title>CMS后台登录界面</title>
<!-- Bootstrap core CSS -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<script src="../../assets/js/ie-emulation-modes-warning.js"></script>
<!-- Custom styles for this template -->
<!-- <link href="signin.css" rel="stylesheet">-->
<!-- 这里引用自己的css模板文件 模板中引用静态资源文件使用url_for,路径filename='cms/css/signin,css')需要相对路径中的绝对路径-->
<link href="{{ url_for('static', filename='cms/css/signin.css') }}" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- 添加登录方法method="post" -->
<form class="form-signin" method="post">
<h2 class="form-signin-heading">请登录</h2>
<label for="inputEmail" class="sr-only">邮箱</label>
<!-- 表单提交根据name="email"来接收后端数据 -->
<input type="email" id="inputEmail" name="email" class="form-control" placeholder="邮箱地址" required autofocus>
<label for="inputPassword" class="sr-only">密码</label>
<!-- 表单提交根据name="password"来接收后端数据 -->
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="填写密码" required>
<div class="checkbox">
<label>
<!-- 表单提交根据name="remember"来接收后端数据 -->
<input type="checkbox" value="remember-me" name="remember"> 记住我
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">立即登录</button>
</form>
</div> <!-- /container -->
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../assets/js/ie10-viewport-bug-workaround.js"></script>
</body>
</html>
前端静态资源文件:signin.css文件
body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #eee;
}
.form-signin {
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin .checkbox {
font-weight: normal;
}
.form-signin .form-control {
position: relative;
height: auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 10px;
font-size: 16px;
}
.form-signin .form-control:focus {
z-index: 2;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
修改:后台视图文件:apps/cms/views.py
# -*- encoding: utf-8 -*-
"""
@File : views.py
@Time : 2020/5/11 9:59
@Author : chen
"""
# 蓝图文件:实现模块化应用,应用可以分解成一系列的蓝图 后端的类视图函数写在这个文件
from flask import Blueprint, render_template, views # 定义类视图,显示模板文件
cms_bp = Blueprint("cms", __name__, url_prefix='/cms/') # URL前缀url_prefix
@cms_bp.route("/") # 后台界面
def index():
return "cms index:后端类视图文件"
# 定义类视图,显示模板文件
class LoginView(views.MethodView):
def get(self):
return render_template("cms/cms_login.html")
# 添加登录路由
cms_bp.add_url_rule("/login/", view_func=LoginView.as_view('login')) # view_func 命名操作名字,"/login/"路由地址
完成界面: