app.py 数据库采用Flaks-SQLAlchemy进行操作
import time
from flask import Flask, render_template, url_for,request,redirect,flash
from flask_sqlalchemy import SQLAlchemy
import os
import click
app = Flask(__name__)
app.config['SECRET_KEY'] = '20190847'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(app.root_path, 'data.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 关闭对模型修改的监控
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.INTEGER, primary_key=True)
name = db.Column(db.String(100))
class Players(db.Model):
id = db.Column(db.INTEGER, primary_key=True)
playername = db.Column(db.String(30))
position = db.Column(db.String(30))
number = db.Column(db.INTEGER)
@app.cli.command() # 注册为命令
@click.option('--drop', is_flag=True, help='Create after drop.')
# 设置选项
def initdb(drop):
"""Initialize the database."""
if drop: # 判断是否输入了选项
db.drop_all()
db.create_all()
click.echo('数据库初始化成功') # 输出提示信息
@app.cli.command()
def forge():
"""Generate fake data."""
from app import User, Players
# 全局的两个变量移动到这个函数内 初始数据库
username = '东北大学工商管理学院'
players = [
{'playername': 'Messi', 'position': 'GodMan', 'number': 30},
{'playername': '朱文甫', 'position': '右边翼卫(RWB)', 'number': 21},
{'playername': '马尔蒂尼', 'position': '左后卫(LB)', 'number': 3},
{'playername': 'Van dank', 'position': '中后卫(CB)', 'number': 2},
{'playername': 'Ramos', 'position': '中后卫(CB)', 'number': 4},
{'playername': 'Kante', 'position': '防守型后腰(CDM)', 'number': 6},
{'playername': '德布劳内', 'position': '前腰(CAM)', 'number': 17},
{'playername': 'Neymar JR', 'position': '前腰(CAM)', 'number': 11},
{'playername': 'Mambape', 'position': '左边锋(LW)', 'number': 7},
{'playername': 'Haaland', 'position': '中锋(ST)', 'number': 9},
{'playername': '多纳鲁马', 'position': '门将(GK)', 'number': 1},
]
user = User(name=username)
db.session.add(user)
for i in players:
player = Players(playername=i['playername'], position=i['position'], number=i['number'])
db.session.add(player)
db.session.commit()
click.echo("虚拟数据添加成功")
@app.context_processor
def inject_user():
user = User.query.first()
return dict(name=user.name)
@app.route('/',methods=['GET','POST'])
def index():
#判断请求如果是POST请求
if request.method == 'POST':
playername = request.form.get('addplayername')
position = request.form.get('addposition')
number = request.form.get('addnumber')
if playername or position or number:#如果输入符合添加要求
player_add1 = Players(playername = playername,position = position,number = number)
db.session.add(player_add1)
db.session.commit()#提交数据库参数
flash("新球员添加成功")#成功提示
return redirect(url_for('index'))#重定向回主页
#如果收到的是GET
players = Players.query.all()
return render_template('index.html',players=players)
@app.route('/player/edit/<int:player_id>',methods=['GET','POST'])
def edit(player_id):
player = Players.query.get_or_404(player_id)
if request.method =='POST':
edited_name = request.form['edited_name']
edited_positon = request.form['edited_position']
edited_number = request.form['edited_number']
player.playername = edited_name
player.position = edited_positon
player.number = edited_number
db.session.commit()
flash('修改成功!')
return redirect(url_for('index'))
return render_template('edit.html',player=player)
@app.route('/player/delete/<int:player_number>', methods=['POST']) #限定只接受 POST 请求
def delete(player_number):
player = Players.query.get_or_404(player_number) # 获取电影记录
db.session.delete(player) # 删除对应的记录
db.session.commit() # 提交数据库会话
flash('球员删除成功')
return redirect(url_for('index')) # 重定向回主页
@app.route('/test')
def test_for_url():
return url_for('index')
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@app.route('/writerPage')
def writerPage():
return "朱文甫 版权所有 联系方式18365051200"
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% for message in get_flashed_messages() %}
<div class="alert">{{ message }}</div>
{% endfor %}
<title>{{ name }}校园足球数据库系统</title>
<link rel="stylesheet" href="{{ url_for('static', filename='StyleDemo.css') }}" type="text/css">
<link rel="icon" href="{{ url_for('static', filename='东大校徽.jpeg') }}">
</head>
<body>
<h2>欢迎{{ name }}, 您现在可以操作球员数据库系统</h2>
<span>
<form action="/" method="post">
球员姓名 <input type="text" name="addplayername" autocomplete="off" required>
球员位置 <input type="text" name="addposition" autocomplete="off" required>
球员号码 <input type="number" name="addnumber" autocomplete="off" required>
<input class="btn" type="submit" name="submit" value="添加球员">
</form>
</span>
<p>{{ name }}共有{{ players|length }} 位队员,分别是</p>
<ul class="movie-list">
{% for p in players %} {# 迭代 movies 变量 #}
<li>
{{ p.playername }}————{{ p.position }}————{{ p.number }}号
<span class="float-right">
<a class="btn">删除球员</a>
<a class="btn" href="{{ url_for('edit',player_id=p.id) }}">编辑球员</a>
<a class="detail" href="https://www.baidu.com" target="_blank" title="查看此球员详细信息">球员资料详情</a>
</span>
</li>
{# 等同于movie['title'] #}
{% endfor %} {# 使用 endfor 标签结束 for 语句 #}
</ul>
<nav>
<ul>
<li><a href="{{ url_for('index') }}">主页链接在这</a></li>
</ul>
</nav>
<footer>
<small>© 2021 <a href="http://127.0.0.1:5000/writerPage">CopyRight Students of NEU,WenFu Zhu</a></small>
</footer>
</body>
</html>
edit.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% for message in get_flashed_messages() %}
<div class="alert">{{ message }}</div>
{% endfor %}
<title>修改球员</title>
<link rel="stylesheet" href="{{ url_for('static', filename='StyleDemo.css') }}" type="text/css">
<link rel="icon" href="{{ url_for('static', filename='东大校徽.jpeg') }}">
</head>
<body>
<h2>欢迎,您现在可以修改{{ player.playername }}的信息了</h2>
<h3>编辑球员</h3>
<form method="post">
修改后球员姓名<input type="text" name="edited_name" autocomplete="off" requiredvalue="{{ player.playername }}">
修改后位置<input type="text" name="edited_position" autocomplete="off" requiredvalue="{{ player.position }}">
修改后球员号码<input type="number" name="edited_number" autocomplete="off" requiredvalue="{{ player.number }}">
<input class="btn" type="submit" name="submit" value="提交修改申请">
</form>
<nav>
<ul>
<li><a href="{{ url_for('index') }}">主页链接在这</a></li>
</ul>
</nav>
<footer>
<small>© 2021 <a href="http://127.0.0.1:5000/writerPage">CopyRight Students of NEU,WenFu Zhu</a></small>
</footer>
</body>
</html>
styledemo.css
}
/* 球员列表 */
.movie-list {
list-style-type: none;
padding: 0;
margin-bottom: 10px;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}
.movie-list li {
padding: 12px 24px;
border-bottom: 1px solid #ddd;
}
.movie-list li:last-child {
border-bottom:none;
}
.movie-list li:hover {
background-color: #f8f9fa;
}
/* 详情键按钮 */
nav ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
nav li {
float: left;
}
nav li a {
display: block;
color: white;
text-align: center;
padding: 8px 12px;
text-decoration: none;
}
nav li a:hover {
background-color: #111;
}
.float-right {
float: right;
}
.detail{
font-size: 12px;
font-weight: bold;
color: black;
text-decoration: none;
background: cyan;
border-radius: 5px;
padding: 3px 5px;
}
/* 表单格式 */
input[type=submit] {
font-family: inherit;
}
input[type=text] {
border: 1px solid #ddd;
}
input[type="text"] {
width: 80px;
}
input[type="number"] {
width: 50px;
}
.btn {
font-size: 12px;
padding: 3px 5px;
text-decoration: none;
cursor: pointer;
background-color: white;
color: black;
border: 1px solid #555555;
border-radius: 5px;
}
.btn:hover {
text-decoration: none;
background-color: black;
color: white;
border: 1px solid black;
}
/* 消息格式 */
.alert {
position: relative;
padding: 7px;
margin: 7px 0;
border: 1px solid transparent;
color: #004085;
background-color: #cce5ff;
border-color: #b8daff;
border-radius: 5px;
}