本文主要详解了使用mysql连接pycharm数据库,利用Flask架构搭建电影管理系统登录界面的方法流程。本项目涉及的完整代码均已上传,含详细注释,供读者学习和参考![提取码:wyfb]
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
__authoer__="star"
# 1.设置名称
app = Flask(__name__)
'''
2.数据库连接设置
'''
# 2.1 设置mysql连接参数
# mysql+pymysql==>mysql数据库+pymysql的驱动模块
# root:mysql===>用户名和密码
# 127.0.0.1:3306 ==>ip地址本机+3306端口号 localhost公认的本机地址
# movie===>数据库名称
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://user:[email protected]:3306/mov'
# 2.2 设置mysql对象修改与信号发送
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
'''
3.设置项目缓存
'''
# 3.1设置缓存URL
app.config['REDIS_URL'] = 'redis://127.0.0.1:6379/0'
# 3.2 设置秘钥
app.config['SECRET_KEY'] = 'star_movie'
# 3.3 设置上传目录
# os.path.join ===>目录拼接
# os.path.abspath===>绝对路径 E:\PycharmProjects\SFMovie
# os.path.dirname(__file__)===>E:\PycharmProjects\SFMovie\static\uploads\
# 后端上传目录
app.config['UP_DIR'] = os.path.join(os.path.abspath(os.path.dirname(__file__)),"static/uploads/")
# 前端上传 目录
app.config['FC_DIR'] = os.path.join(os.path.abspath(os.path.dirname(__file__)),"static/uploads/users")
# 4.设置DEBUG模式
app.debug = False
# 5.数据库连接
# 5.1 获取连接通道
db = SQLAlchemy(app)
# 6.设置缓存机制
rd = FlaskRedis(app)
这里需要注意的有两个地方:
a.数据库的设置方式,用户名,密码,数据库名称应对应准确;127.0.0.1是本机服务器,若想使用同一局域网的其他主机的数据库可输入对应的ip即可。
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://user:[email protected]:3306/mov'
b.设置debug模式,如果出现500等无法显示情况,将app.debug设置为True,重启计算机后,可在浏览器中看到Trace_back的报错情况进行调试。
app.debug = False
在_ init _.py中,继续添加以下代码:
'''
7.蓝图 提高编程效率
'''
# 7.1 设置导入蓝图
from app.admin import admin as admin_blueprint
# 7.2 注册蓝图
app.register_blueprint(admin_blueprint)
连接方法,参考博客:https://blog.csdn.net/sinat_40770656/article/details/107384070
该部分代码在app/models.py文件中编写完成。
admin表的属性值如下:
编写代码如下:
from app import db
from datetime import datetime
'''
1.admin表
'''
# 管理员表
class Admin(db.Model):
# 1.设置表格名称
__tablename__='admin'
# 2.用户是否存在
__table_args__ = {'useexisting':True}
# 3.设置映射
# 编号
id = db.Column(db.Integer,primary_key=True)
# 账号 姓名
name = db.Column(db.String(100),unique=True)
# 管理员密码
pwd = db.Column(db.String(100))
# 超级管理员
is_super = db.Column(db.SmallInteger)
# 管理员角色
role_id = db.Column(db.Integer,db.ForeignKey('role.id'))
# 添加时间 默认是当前时间
addTime = db.Column(db.DateTime,index=True,default=datetime.now)
'''
添加管理员日志
'''
# 管理员登录日志外键关联
adminlogs = db.relationship('Adminlog',backref='admin')
# 管理员操作操作日志外键关联
oplogs = db.relationship('Oplog',backref='admin')
# 显示对象属性
def __repr__(self):
return '' %self.name
# 检查密码是否正确
def check_pwd(self,pwd):
return self.pwd == pwd
'''
2.管理员的登录日志 adminlog
'''
class Adminlog(db.Model):
# 1.设置表名称
__tablename__ = 'adminlog'
# 2.判断表是否存在
__table_args__ = {'useexisting':True}
# 3.设置字段信息
id = db.Column(db.Integer,primary_key=True)
admin_id = db.Column(db.Integer,db.ForeignKey('admin.id'))
ip = db.Column(db.String(100))
addtime = db.Column(db.DateTime,index=True,default=datetime.now)
# 4.设置 返回表信息
def __repr__(self):
return "" %self.id
'''
3.管理员的操作日志 Oplog
'''
class Oplog(db.Model):
# 1.表名称
__tablename__ = 'oplog'
# 2.判断表是否存在
__table_args__ = {'useexisting':True}
# 3.表信息
id = db.Column(db.Integer,primary_key=True)
admin_id = db.Column(db.Integer,db.ForeignKey('admin.id'))
ip = db.Column(db.String(100))
# 操作原因
reason = db.Column(db.String(600))
# 添加时间
addTime = db.Column(db.DateTime,index=True,default=datetime.now)
def __repr__(self):
return "" %self.id
from flask import render_template,flash,redirect,url_for,session,request
from . import admin
from .forms import LoginForm,TagForm
from app.models import Admin,Adminlog,Tag
from app import db
'''
1.后台系统请求设置
GET=>返回的是 网页login.html
POST===>表单提交 判断用户名存在 密码一致
'''
@admin.route('/login/',methods=['GET','POST'])
def login():
# 1.设置表单form变量
form = LoginForm()
# 2.判断是否提交按钮 登录按钮被按下
if form.validate_on_submit():
# 3.获取表单数据
userData = form.data
# 4.判断账号是否一致 Admin===>Models文件中Admin表
admin = Admin.query.filter_by(name=userData['account']).first()
# 5.判断用户密码与数据库密码是否一致
if not admin.check_pwd(userData['pwd']):
# 通过flash发送错误信息
flash('密码错误','err')
# 重定向请求
return redirect(url_for('admin.login'))
# 6.存储session
session['admin'] = userData['account']
session['admin_id'] = admin.id
# 7.设置管理员登录日志
adminlog = Adminlog(
admin_id = admin.id,
ip = request.remote_addr
)
# 8.添加登录日志 insert into
db.session.add(adminlog)
db.session.commit()
# 9.重定向
# 当需要获取前端页面表单传过来的id值的时候,我们就需要request.args.get
# 而不能用request.form
return redirect(request.args.get('next') or url_for("admin.index") )
return render_template('admin/login.html',form=form)
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, FileField, TextAreaField
from wtforms.validators import DataRequired, ValidationError
# 导入数据库映射文件 Admin是表格名称 models是数据库所有表格的映射
from app.models import Admin
'''
1.管理员登录表单映射
'''
class LoginForm(FlaskForm):
# validators:验证器
# description:描述
# render_kw:渲染属性
# 账号信息处理
account = StringField(
label='账号',
validators=[DataRequired('账号不能为空')],
description='管理员账号',
render_kw={'class': 'form-control', 'placeholder': '请输入管理员账号'}
)
# 密码
pwd = PasswordField(
label='密码',
validators=[DataRequired('密码不能为空')],
description='管理员密码',
render_kw={'class': 'form-control', 'placeholder': '请输入管理员密码'}
)
# 登录按钮
submit = SubmitField(
label='登录',
render_kw={'class': 'btn btn-primary btn-block btn-flat'}
)
# 当我们登录的时候在数据库没有查找用户信息
def validat_account(self, field):
# 获取验证数据信息
account = field.data
# 查找统计数据库中的用户名数量
admin = Admin.query.filter_by(name=account).count()
# 判断是否为0
if admin == 0:
raise ValidationError('账号不存在')
这里需要注意的是:
a.Admin是表格名称,models是数据库所有表格的映射。
b.原始的管理员名称是admin,密码是admin。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>后台| 电影管理系统</title>
<!--解决IE浏览器兼容问题-->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--width=device-width:页面的可视区域宽度-->
<!--initial-scale=?:显示可视区域缩放级别1.0-->
<!--maximum-scale=?:最大缩放值-->
<!--minimum-scale=?:最小缩放值-->
<!--use-scalable=yes/no:表示用户可以手动缩放比例-->
<!--name='viewport':手机端页面虚拟窗口-->
<meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
<!--加载css样式文件-->
<link rel = 'shortcut icon' href="{{ url_for('static',filename='base/images/logo.png')}}">
<link rel='stylesheet' href="{{ url_for('static',filename='admin/bootstrap/css/bootstrap.min.css') }}">
<link rel='stylesheet' href="{{ url_for('static',filename='fonts/css/font-awesome.min.css') }}">
<link rel='stylesheet' href="{{ url_for('static',filename='ionicons/css/ionicons.min.css') }}">
<link rel='stylesheet' href="{{ url_for('static',filename='admin/dist/css/AdminLTE.min.css') }}">
<link rel='stylesheet' href="{{ url_for('static',filename='admin/plugins/iCheck/square/blue.css') }}">
</head>
<body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<a href="#"><b>电影管理系统</b></a>
</div>
<div class="login-box-body">
<!--设置登录信息显示-->
<!--失败-->
{% for msg in get_flashed_messages(category_filter=['err']) %}
<p class="login-box-msg" style="color: red">{{ msg }}</p>
{% endfor %}
<!--成功-->
{% for msg in get_flashed_messages(category_filter=['ok']) %}
<p class="login-box-msg" style="color: green">{{ msg }}</p>
{% endfor %}
<!--设置表单提交-->
<form method="post" id="form-data">
<!--账号-->
<div class="form-group has-feedback">
{{ form.account }}
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
{% for err in form.account.errors %}
<p style="color: red;">{{ err }}</p>
{% endfor %}
</div>
<!--密码-->
<div class="form-group has-feedback">
{{ form.pwd }}
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
{% for err in form.pwd.errors %}
<div class="col-md-12">
<p style="color: red">{{ err }}</p>
</div>
{% endfor %}
</div>
<!--提交按钮-->
<div class="row">
<div class="col-xs-8"></div>
<div class="col-xs-4">
<!--保护验证(随机的令牌) 保证大部分工作可以正常进行-->
{{ form.csrf_token }}
{{ form.submit }}
</div>
</div>
</form>
</div>
</div>
<!--script加载不能放在头部-->
<script src="{{ url_for('static',filename='admin/plugins/jQuery/jQuery-2.2.0.min.js') }}"></script>
<script src="{{ url_for('static',filename='admin/bootstrap/js/bootstrap.js') }}"></script>
<script src="{{ url_for('static',filename='admin/plugins/iCheck/icheck.js') }}"></script>
</body>
</html>
{% extends 'admin/admin.html' %}
{% block content %}
<section class="content-header">
<h1>电影管理系统h1>
<ol class="breadcrumb">
<li>
<a href="#">
<i class="fa fa-dashboard">i>
首页
a>
li>
<li class="active">
控制面板
li>
ol>
section>
<section class="content" id="showcontent">
<div class="row">
<div class="col-md-6">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">内存使用率h3>
div>
<div class="box-body" id="meminfo" style="height:600px">
div>
div>
div>
<div class="col-md-6">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">系统设置h3>
div>
<form role="form">
<div class="box-body" style="height: 600px">
<div class="form-group">
<label for="input_speed">限制速率大小label>
<input type="text" class="form-control" id="input_speed" placeholder="请输入限制速率" value="512">
div>
<div class="form-group">
<label for="input_speed">限制内存大小label>
<input type="text" class="form-control" id="input_speed" placeholder="请输入限制内存" value="10m">
div>
<div class="form-group">
<label for="input_speed">限制客户端数量label>
<input type="text" class="form-control" id="input_speed" placeholder="请输入限制客户端数量" value="4">
div>
<div class="form-group">
<button type="submit" class="btn btn-primary">保存并重启服务button>
div>
div>
form>
div>
div>
div>
section>
{% endblock %}
{% block js %}
<script src="{{ url_for('static',filename='js/echarts.min.js') }}">script>
<script>
var myChart = echarts.init(document.getElementById('meminfo'));
option = {
backgroundColor:'white',
tooltip:{formatter:"{a}
{b} : {c}"},
toolbox:{feature:{
restore:{},
saveAsImage:{}}},
series:[
{name:'内存使用率',
type:'gauge',
detail:{
formatter: '{value}%'
},
data:[{
value:50,
name:'内存使用率'
}]
}
]
};
setInterval(function () {
option.series[0].data[0].value = (Math.random()*100).toFixed(2)-0;
maChart.setOption(option,true);
},2000)
script>
<script>
$(document).ready(function () {
$('#g-1').addClass('active');
$('#g-1-1').addClass('active');
});
script>
{% endblock %}