上传头像
2018-01-18 本文已影响0人
马梦里
- 在 User 类中增加字段:
@classmethod
def valid_names(cls):
names = super().valid_names()
names = names + [
('username', str, ''),
('password', str, ''),
('user_image', str, '/uploads/default.png'),
]
return names
注意:
数据库中 user_image 中存储的是图片的路径,而非文件实体,所以数据类型为字符串;
- 建立上传头像的表单
<form method=post
action='{{ url_for(".add_img") }}'
enctype=multipart/form-data>
<input type=file name=avatar>
<!--<input type=submit value=Upload>-->
<button type="submit">Upload</button>
</form>
<img src="{{ user.user_image }}" title="avatar"/>
- 以二进制上传,所以
enctype=multipart/form-data
- 编写函数
def valid_suffix(suffix):
valid_type = ['jpg', 'png', 'jpeg']
return suffix in valid_type
@main.route('/image/add', methods=["POST"])
def add_img():
u = current_user()
file = request.files['avatar']
suffix = file.filename.split('.')[-1]
if valid_suffix(suffix):
filename = '{}.{}'.format(str(uuid.uuid4()), suffix)
file.save(os.path.join('user_image', filename))
User.update(u.id, dict(
user_image='/uploads/' + filename
))
return redirect(url_for(".profile"))
@main.route("/uploads/<filename>")
def uploads(filename):
return send_from_directory('user_image', filename)
- 获取文件用:
request.files[' ']- post 方法
request.form - get 方法
request.get(' ')
- post 方法
- 重新构造文件名防止 web 攻击
- 用 . 将扩展名和文件名分开
- 生成随机字符串为文件名
- 将真正文件存储至 根目录 的
user_image/filename
下
文件本身是二进制格式存储,存储在相应的扩展名下。
- 更新 User 类的 user_image 字段,这里存储的是文件名。
- uploads() 函数根据 文件名 ,在指定路径下返回文件
这样就把静态资源的请求和一般的请求分开了。静态资源的请求可以交给 nginx ,其他请求的处理交给 gunicorn。
<img src={{ u.user_image }}>:
<img src="/uploads/d220679e-5c27-44e5-9876-cf155bcaa223.jpg" title="avatar"/>
这是一个相对路径,完整的是:
http://localhost:7000/uploads/filename
加载图片时,会自动访问图片的路径,那么就会启动 /uploads 路由对应的函数,根据变量 filename 去指定文件夹下获取文件。