前言
在开发flask项目的时候,难免会遇到文件传输的需求,现在就以上传用户头像为例,说一下在flask中文件如何上传。
一、环境
python 3.7 flask 2.0.2
二、使用
本篇博客代码接着上一篇博客flask使用redis继续写,项目目录如下
1.更新模型类
因为现在要添加头像,所以模型类也要添加对应字段。 models.py
from . import db
class Test(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(10))
password = db.Column(db.String(20))
sex = db.Column(db.String(2))
avatar_url = db.Column(db.String(256))
def to_dict(self):
test_dict = {
'id': self.id,
'name': self.name,
'sex': self.sex,
'avatar_url': self.avatar_url
}
return test_dict
然后输入如下命令将更改更新到数据库:
python manage.py db migrate
python manage.py db upgrade
2.更改视图和模板
在上面我增加了性别,所以注册视图和模板要做相应的修改 flask_teach/test/views.py
from flask import request, render_template, redirect, session, url_for, jsonify, current_app
from . import test_blue
from flask_teach import db, models, redis_store
from flask_teach.decorators import decorator_login
from flask_teach.common import random_num
@test_blue.route('/register', methods=['POST', 'GET'])
def register():
if request.method == 'GET':
return render_template('test/register.html')
else:
name = request.form['name']
password = request.form['password']
sex = request.form['sex']
user = models.Test.query.filter_by(name=name).first()
if user:
return "该用户已存在"
test = models.Test(name=name, password=password, sex=sex)
db.session.add(test)
return "注册成功!!!"
register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form action="/test/register" method="post">
用户名:<input type="text" name="name"><br>
密码:<input type="password" name="password"><br>
性别:<input type="radio" name="sex" checked value="男">男
<input type="radio" name="sex" value="女">女
<br>
<input type="submit" value="注册">
</form>
</body>
</html>
3.编写视图
用户头像上传是在用户信息里面上传,所以要编写一个用户信息视图。 flask_teach/test/views.py
from flask import request, render_template, redirect, session, url_for, jsonify, current_app
from . import test_blue
from flask_teach import db, models, redis_store
from flask_teach.decorators import decorator_login
from flask_teach.common import random_num
......
@test_blue.route('/user_message', methods=['GET', 'POST'])
@decorator_login
def user_update():
name = session.get('name')
user = models.Test.query.filter_by(name=name).first()
user_dict = user.to_dict()
if request.method == 'GET':
return render_template('test/user_message.html', user=user_dict)
else:
name = request.form['name']
sex = request.form['sex']
avatar = request.files.get('avatar')
if avatar:
absolute_avatar_path = current_app.static_folder + '/avatar/{}.png'.format(name)
with open(absolute_avatar_path, 'wb+') as f:
f.write(avatar.read())
f.close()
user.avatar_url = absolute_avatar_path
user.name = name
user.sex = sex
session['name'] = name
user_dict = user.to_dict()
return render_template('test/user_message.html', user=user_dict)
编写模板 user_message.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户信息</title>
<script src="../../static/js/jquery-3.6.0.min.js"></script>
<style>
img {
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<img src="/test/user_avatar" alt="" id="avatar_img">
<form action="/test/user_message" enctype="multipart/form-data" method="post">
用户头像:<input type="file" name="avatar" id="avatar"><br>
用户名:<input type="text" value="{{user.name}}" name="name"><br>
性别:
{% if user.sex== '男' %}
<input type="radio" value="男" checked name="sex">男
<input type="radio" value="女" name="sex">女
{% else %}
<input type="radio" value="男" name="sex">男
<input type="radio" value="女" checked name="sex">女
{% endif %}
<br>
<input type="submit" value="提交">
</form>
<a href="/test/index">返回首页</a>
<script>
$(function () {
$('#avatar').change(function () {
let avatar_img = new FileReader()
let up_avatar = $(this)[0].files[0];
avatar_img.readAsDataURL(up_avatar)
avatar_img.onload = function () {
$('#avatar_img').attr('src', avatar_img.result)
}
})
})
</script>
</body>
</html>
前端发送获取文件的请求时,服务器要返回对应文件,因此在这里专门编写一个返回用户头像的视图 flask_teach/test/views.py
from flask import request, render_template, redirect, session, url_for, jsonify, current_app
from . import test_blue
from flask_teach import db, models, redis_store
from flask_teach.decorators import decorator_login
from flask_teach.common import random_num
@test_blue.route('/user_avatar')
def user_avatar():
name = session.get('name')
user = models.Test.query.filter_by(name=name).first()
if not user.avatar_url:
if user.sex == '男':
return current_app.send_static_file('avatar/male.jpeg')
if user.sex == '女':
return current_app.send_static_file('avatar/female.jpeg')
return current_app.send_static_file('avatar/{}.png'.format(name))
运行
先注册一个用户
注册之后登录查看用户信息 更改信息后点提交 可以看到数据已经更新,后台也保存了对应图片 大功告成!!!有什么问题欢迎在评论区留言。 所有代码已经传到了码云上https://gitee.com/li_weiyan/flask_teach.git,有兴趣的可以看一下。
|