所需环境
MySQL 8.0
Redis
Python 3.9
所需软件
MySQL
Redis
PyCharm
首先,在MySQL中创建数据库名称为dwz:
准备工作
对所需软件与Python包进行装载:
pip install flask
pip install flask-sqlalchemy
pip install flask_redis
实现过程
在该文件列表下建立templates、static目录以及app.py文件:
custom.css文件:
* {
margin: 0;
}
html, body {
height: 100%;
}
#content {
margin-top: 20px;
margin-bottom: 60px;
}
header {
margin-bottom: 30px;
padding-bottom: 10px;
clear: both;
}
#wrap {
margin: 5px 10px -50px 10px;
padding: 10px;
text-align: center;
min-height: 100%;
}
#url-result {
color: #039be5;
display: hidden;
}
.btn {
float: right;
}
footer {
color: #039be5;
text-align: center;
height: 50px;
line-height: 50px;
}
footer a{
color: #039be5;
}
index.html文件:
<!DOCTYPE html>
<html>
<head>
<title>短网址服务</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css">
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/custom.css') }}">
</head>
<script type="text/javascript">
$(function() {
$('#submitButton').click(function() {
$.ajax({
// 发送方式
type: "POST",
// 规定url地址
url: "/shorten",
// 发送数据的格式JSON
dataType: 'json',
contentType: "application/json",
// 要发送的数据
data: JSON.stringify({'url' : $('#url').val()}),
// 如果服务器响应200则会被调用
success: function(json) {
if(json.url) {
$('#url-result').text(json.url);
$('#url').val("");
$("a").attr("href", json.url)
} else {
$('#url-result').text("请输入一个URL!");
}
},
error: function() {
alert("服务器异常");
}
});
});
});
</script>
<body>
<div id="wrap">
<header>
<h1><a href="">短网址服务</a></h1>
<p>请输入一个网址</p>
</header>
<div class="container">
<div class="row">
<div class="col s12">
<input type="text" name="url" id="url" class="form-control input-sm" placeholder="请输入一个合法的网址" />
</div>
</div>
<div class="row">
<div class="col s4 offset-s4">
<button id="submitButton" class="waves-effect waves-light btn-large blue darken-1">生成</button>
</div>
</div>
<div class="row">
<div class="col s12">
<div class="panel-footer">
<h4>
<a href="#" id="url-result">输入 URL</a>
</h4>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
实现代码
导入包:
from flask import Flask, jsonify, render_template, request
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
连接MySQL以及Redis:
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:000000@127.0.0.1:3306/dwz"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
redis_store = FlaskRedis(app)
对字符串进行范围设定:
CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
设置数据库模型:
class Store(db.Model):
id = db.Column(db.Integer, primary_key=True)
token = db.Column(db.String(7), index=True)
url = db.Column(db.String(256), unique=True)
实现短网址算法:
def encode(num):
if num == 0:
return CHARS[0]
res = []
while num:
num, rem = divmod(num, len(CHARS))
res.append(CHARS[rem])
return ''.join(reversed(res))
输入对网址进行判断:
@app.route('/shorten', methods=['POST'])
def short_url():
long_url = request.json['url']
if not long_url:
return jsonify(url="请输入长网址,输入不能为空")
if Store.query.filter_by(url=long_url).all():
return jsonify(url="你输入网址已存在,请重新输入!")
其余设定:
index = int(redis_store.incr('CNT'))
token = encode(index)
store = Store(token=token, url=long_url)
db.session.add(store)
db.session.commit()
short_url = 'https://LQ.com/' + token
return jsonify(url=short_url)
连接index文件:
@app.route('/')
def index():
return render_template('index.html')
运行函数:
if __name__ == "__main__":
app.run(debug=True)
完全代码:
from flask import Flask, jsonify, render_template, request
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
import pymysql
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:000000@127.0.0.1:3306/dwz"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
redis_store = FlaskRedis(app)
CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
class Store(db.Model):
id = db.Column(db.Integer, primary_key=True)
token = db.Column(db.String(7), index=True)
url = db.Column(db.String(256), unique=True)
def encode(num):
if num == 0:
return CHARS[0]
res = []
while num:
num, rem = divmod(num, len(CHARS))
res.append(CHARS[rem])
return ''.join(reversed(res))
@app.route('/shorten', methods=['POST'])
def short_url():
long_url = request.json['url']
if not long_url:
return jsonify(url="请输入长网址,输入不能为空")
if Store.query.filter_by(url=long_url).all():
return jsonify(url="你输入网址已存在,请重新输入!")
index = int(redis_store.incr('CNT'))
token = encode(index)
store = Store(token=token, url=long_url)
db.session.add(store)
db.session.commit()
short_url = 'https://LQ.com/' + token
return jsonify(url=short_url)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
运行方法
在PyCharm的终端输入flask shell;
在进入该条件下输入,进行数据库的创建:
from app import db
db.create_all()
再次到终端下输入flask run
点击产生的网址链接,产生的效果:
输入网址,生成的短网址如下:
与此同时,数据库内store表的变化:
Redis为计数器生成: