环境:pycharm + python2.7.15
完成功能:
邮件发送,以及文件上传,以及对数据库的增删查操作
备注:我不是写flask的,只是临时需要,写了一个小demo差不多的,方便以后查阅
管理员:
查找,增加,删除,文件上传(上传到static/images目录)
用户
注册,登陆,邮件发送找回密码
代码:
12161.py
#!/usr/bin/python3.5
# -*- coding: UTF-8 -*-
# 导入数据库模块
import pymysql
import time,datetime
# 导入Flask框架,这个框架可以快捷地实现了一个WSGI应用
from flask import Flask,flash
# 默认情况下,flask在程序文件夹中的templates子文件夹中寻找模块
from flask import render_template
# 导入前台请求的request模块
from flask import request, Response,redirect,session,jsonify
import traceback
from flask_sqlalchemy import SQLAlchemy
from flask_mail import Mail, Message
import cv2
import time
import os
from werkzeug.utils import secure_filename
from models import User
#设置允许的文件格式
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'JPG', 'PNG', 'bmp'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
# 传递根目录
app = Flask(__name__)
app.secret_key = '12161'
app.config['DEBUG']=True
# 默认路径访问登录页面
@app.route('/')
def login():
return render_template('login.html')
# 默认路径访问注册页面
@app.route('/regist')
def regist():
return render_template('regist.html')
@app.route('/logout')
def logout():
return render_template('login.html')
# 设置响应头
def Response_headers(content):
resp = Response(content)
resp.headers['Access-Control-Allow-Origin'] = '*'
return resp
# 获取注册请求及处理
@app.route('/registuser')
def getRigistRequest():
# 把用户名和密码注册到数据库中
# 连接数据库,此前在数据库中创建数据库TESTDB
db = pymysql.connect("localhost", "root", "123456", "lesson")
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 插入语句
sql = "INSERT INTO person(name, psd,age) VALUES (" + request.args.get('username') + ", " + request.args.get(
'password1') + ", " + request.args.get('age')+" )"
try:
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
# 注册成功之后跳转到登录页面
flash("注册成功")
return render_template('login.html')
except:
# 抛出错误信息
traceback.print_exc()
# 如果发生错误则回滚
db.rollback()
return '注册失败'
# 关闭数据库连接
db.close()
# 获取登录参数及处理
@app.route('/login')
def getLoginRequest():
# 查询用户名及密码是否匹配及存在
# 连接数据库,此前在数据库中创建数据库TESTDB
db = pymysql.connect("localhost", "root", "123456", "lesson")
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 查询语句
sql = "select * from person where name="+request.args.get('name')+" and psd="+request.args.get('psd')+""
try:
# 执行sql语句
cursor.execute(sql)
results = cursor.fetchall()
print(len(results))
if len(results) == 1:
# return '登录成功'
User.name = request.args.get('name')
User.psd = request.args.get('psd')
username = request.args.get('name')
userpsd = request.args.get('psd')
session['username'] = username
print(User.name + " "+User.psd)
return render_template('main1.html',name=request.args.get('name'))
else:
return '用户名或密码不正确'
# 提交到数据库执行
db.commit()
except:
# 如果发生错误则回滚
traceback.print_exc()
db.rollback()
# 关闭数据库连接
db.close()
# 查询数据库所有零食信息
@app.route('/all')
def all():
conn = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='lesson', charset='utf8')
cur = conn.cursor()
sql = "SELECT * FROM thing"
cur.execute(sql)
conn.commit()
u = cur.fetchall()
conn.close()
return render_template('main2.html', u=u)
# 增加零食
@app.route('/add', methods=['POST', 'GET'])
def add():
# # 把用户名和密码注册到数据库中
#
# # 连接数据库,此前在数据库中创建数据库TESTDB
# db = pymysql.connect("localhost", "root", "123456", "lesson")
# # 使用cursor()方法获取操作游标
# cursor = db.cursor()
# # SQL 插入语句
# sql = "INSERT INTO thing VALUES ( '" + request.args.get('name') + "' , '" + request.args.get( 'price')+"' )"
# print(sql)
#
# # 执行sql语句
# cursor.execute(sql)
# # 提交到数据库执行
# db.commit()
# db.close()
# # 注册成功之后跳转到登录页面
# flash("增加成功")
if request.method == 'POST':
f = request.files['file']
if not (f and allowed_file(f.filename)):
return jsonify({"error": 1001, "msg": "请检查上传的图片类型,仅限于png、PNG、jpg、JPG、bmp"})
name = request.form.get("name")
price = request.form.get("price")
basepath = os.path.dirname(__file__) # 当前文件所在路径
upload_path = os.path.join(basepath, 'static/images', secure_filename(f.filename)) # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
# upload_path = os.path.join(basepath, 'static/images','test.jpg') #注意:没有的文件夹一定要先创建,不然会提示没有该路径
f.save(upload_path)
# 使用Opencv转换一下图片格式和名称
img = cv2.imread(upload_path)
filename = name + '.jpg'
cv2.imwrite(os.path.join(basepath, 'static/images',filename), img)
db = pymysql.connect("localhost", "root", "123456", "lesson")
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 插入语句
sql = "INSERT INTO thing VALUES ( '" + name + "' , '" + price+"' )"
print(sql)
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
db.close()
return redirect("/all")
return redirect("/all")
@app.route('/delete/')
def delete():
conn = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='lesson', charset='utf8')
cur = conn.cursor()
name = request.args.get("name")
# print(name)
# sql= "delete from thing"
sql = "delete from thing where name='%s' " % (name)
print(sql)
cur.execute(sql)
# 关闭数据库连接
conn.commit()
conn.close()
return redirect("/all")
@app.route('/forget')
def forget():
return render_template('forget.html')
#使用QQ邮箱服务器
app.config['MAIL_SERVER']='smtp.qq.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = '发送者邮箱'
app.config['MAIL_PASSWORD'] = '发送者邮箱的密码'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail = Mail(app)
@app.route('/forget1')
def forget1():
conn = pymysql.connect("localhost", "root", "123456", "lesson")
cursor = conn.cursor()
email = request.args.get('email')
name = request.args.get('name')
sql = "update person set psd = '123456' where name = '"+name+"'"
print(sql)
cursor.execute(sql)
# 关闭数据库连接
conn.commit()
conn.close()
msg = Message('修改密码', sender='[email protected]', recipients=[email])
msg.body = "您的密码已经被修改为123456,请登录修改密码"
mail.send(msg)
return redirect("/")
@app.route('/userallfood')
def userallfood():
conn = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='lesson', charset='utf8')
cur = conn.cursor()
sql = "SELECT * FROM thing"
cur.execute(sql)
conn.commit()
u = cur.fetchall()
conn.close()
return render_template('userallfood.html', u=u)
@app.route('/buy/')
def buy():
conn = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='lesson', charset='utf8')
cur = conn.cursor()
# 获得要购买的零食名字
name = request.args.get("name")
# 获得用户名
username= session.get('username')
# print ('当前登录用户:'+username)
time = datetime.datetime.now()
stringtime = str(time)
print(stringtime)
sql = "INSERT INTO guanxi VALUES ( '" + username + "' , '" + name + "','"+stringtime+"' )"
print(sql)
cur.execute(sql)
# 关闭数据库连接
conn.commit()
conn.close()
return redirect("/userallfood")
@app.route('/userbuyrecord')
def userbuyrecord():
conn = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='lesson', charset='utf8')
cur = conn.cursor()
# 获得用户名
username = session.get('username')
sql = "SELECT * FROM guanxi where name = '"+username+"'"
cur.execute(sql)
conn.commit()
u = cur.fetchall()
conn.close()
return render_template('userbuyrecord.html', u=u)
@app.route('/upload', methods=['POST', 'GET']) # 添加路由
def upload():
if request.method == 'POST':
f = request.files['file']
if not (f and allowed_file(f.filename)):
return jsonify({"error": 1001, "msg": "请检查上传的图片类型,仅限于png、PNG、jpg、JPG、bmp"})
user_input = request.form.get("name")
basepath = os.path.dirname(__file__) # 当前文件所在路径
upload_path = os.path.join(basepath, 'static/images', secure_filename(f.filename)) # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
# upload_path = os.path.join(basepath, 'static/images','test.jpg') #注意:没有的文件夹一定要先创建,不然会提示没有该路径
f.save(upload_path)
# 使用Opencv转换一下图片格式和名称
img = cv2.imread(upload_path)
cv2.imwrite(os.path.join(basepath, 'static/images', 'test.jpg'), img)
return render_template('upload_ok.html', userinput=user_input, val1=time.time())
return render_template('upload.html')
# 使用__name__ == '__main__'是 Python 的惯用法,确保直接执行此脚本时才
# 启动服务器,若其他程序调用该脚本可能父级程序会启动不同的服务器
if __name__ == '__main__':
app.run(debug=True)
main2.html(管理员界面,包含增删查以及文件上传操作,上传过程中修改文件名)
{# 管理员界面 #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>管理员界面</title>
<link rel="stylesheet" href="static/css/login_regist.css">
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h3 class="page-title" align="center">增加零食信息</h3>
<form action="/add" enctype='multipart/form-data' method='POST'>
<div class="form-container">
<div class="form-group">
<input type="file" name="file" style="margin-top:20px;"/>
<br>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="零食名" name="name">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="价格" name="price">
</div>
<div class="form-group">
<button class="btn btn-primary btn-block">增加</button>
</div>
</div>
</form>
</br>
<p align="center">所有商品信息</p>
<table class="table table-bordered" border="2" align="center">
<tr>
<th>零食图片</th>
<th>零食名称</th>
<th>零食价格</th>
<th>删除该商品</th>
</tr>
{% for i in u %}
<tr>
<td>
<img src="static/images/{{ i[0] }}.jpg" width="30px" height="30px">
</td>
<td>{{ i[0] }}</td>
<td>{{ i[1] }}</td>
<td>
<a href="/delete/?name={{i[0]}}">
删除该商品
</a>
</td>
</tr>
{% endfor %}
</table>
</body>
</html>
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}-知了课堂问答平台</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="{{ url_for('static',filename='css/base.css') }}">
{% block head %}{% endblock %}
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active">
<a href="/">首页<span class="sr-only">(current)</span></a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
{# {% if user %}#}
{# <li><a href="#">{{ user.username }}</a></li>#}
{# <li><a href="{{ url_for('logout') }}">注销</a></li>#}
{# {% else %}#}
{# <li><a href="{{ url_for('login') }}">登录</a></li>#}
{# <li><a href="{{ url_for('regist') }}">注册</a></li>#}
{# {% endif %}#}
<li><a href="{{ url_for('login') }}">登录</a></li>
<li><a href="{{ url_for('regist') }}">注册</a></li>
<li><a href="{{ url_for('forget') }}">忘记密码</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="main">
{% block main %}{% endblock %}
</div>
</body>
</html>
forget.html (发送邮件功能)
{% extends 'base.html' %}
{% block title %}登录{% endblock %}
{% block head %}
<link rel="stylesheet" href="{{ url_for('static',filename='css/login_regist.css') }}">
{% endblock %}
{% block main %}
<h3 class="page-title">找回密码</h3>
<form action="/forget1" method="GET">
<div class="form-container">
<div class="form-group">
<input type="text" class="form-control" placeholder="邮箱" name="email">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="用户名" name="name">
</div>
<div class="form-group">
<button class="btn btn-primary btn-block">提交</button>
</div>
</div>
</form>
{% endblock %}
login.html(登陆界面)
{% extends 'base.html' %}
{% block title %}登录{% endblock %}
{% block head %}
<link rel="stylesheet" href="{{ url_for('static',filename='css/login_regist.css') }}">
{% endblock %}
{% block main %}
<h3 class="page-title">登录</h3>
<form action="/login" method="GET">
<div class="form-container">
<div class="form-group">
<input type="text" class="form-control" placeholder="用户名" name="name">
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="密码" name="psd">
</div>
<div class="form-group">
<button class="btn btn-primary btn-block">登录</button>
</div>
</div>
</form>
{% endblock %}
部分问题整理
flask使用 secure_filename()获取中文文件名问题
flask上传文件代码参考
flask邮件发送参考
flask原生sql语句操作mysql数据库参考