我正在努力解決以下問題:在 Flask 中提供媒體檔案的正確方法是什么?我Posts在博客系統中建立了一個模型,我正在使用flask-file-upload
# models/blog.py
from app import db, file_upload
@file_upload.Model
class Posts(db.Model):
"""
Defines the attributes of posts table in the database
"""
...
image = file_upload.Column()
...
在我的settings.py檔案中我有
import os
from pathlib import Path
PROJECT_ROOT = Path(__file__).parent.parent
UPLOAD_FOLDER = os.path.join(PROJECT_ROOT, 'media')
因此,當我添加 Post 物件時,它會將檔案名保存在資料庫中,并將檔案保存在帶有路徑的媒體檔案夾中 media/posts/<post_id>/filename
到目前為止,它作業得很好。但我需要提供這些影像,所以我創建了以下路線:
# routes.py
from app import app
@app.get('/media/<path:path>')
def send_media(path):
"""
:param path: a path like "posts/<int:post_id>/<filename>"
:return:
"""
path_list = path.split('/')
path_ = '/'.join(path_list[:-1]) '/'
file_name = path_list[-1]
return send_from_directory(
directory=app.config['UPLOAD_FOLDER'], path=path_, filename=file_name, as_attachment=True
)
但它不起作用,當我瀏覽時 http://127.0.0.1:5000/media/posts/15/python.jpg
我的 Flask 應用程式回應 404 - Not Found,即使是 python.jpg 檔案也在那里。

如何正確訪問 Flask 中的媒體檔案?我需要這個,因為我必須創建一個 API 來發送file_name和前端將呈現影像,像
<img src="http://localhost:8000/media/posts/<post_id>/file_name">
uj5u.com熱心網友回復:
在我看來,flask-file-upload 擴展基本上使用了一個upload_folder,它位于靜態檔案夾中。如果指定了不同的位置,上傳也可以作業,但 get_file_url 函式沒有回傳正確的位置。此外,需要單獨的下載路徑,因為您要在此處創建。
如果您指定了一個檔案夾,如檔案中所示,該檔案夾位于 static 檔案夾內,那么您的作業會更輕松。
否則,這是我的示例,用于不同的位置。這不是最好的方法,但它有效。
import os
from flask import Flask
from flask import render_template, request, send_from_directory
from flask_sqlalchemy import SQLAlchemy
from flask_file_upload.file_upload import FileUpload
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = os.path.join(app.root_path, 'media')
app.config['ALLOWED_EXTENSIONS'] = ['jpg', 'png']
app.config['MAX_CONTENT_LENGTH'] = 1000 * 1024 * 1024 # 1000mb
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.sqlite'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
file_upload = FileUpload(app, db)
@file_upload.Model
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
image = file_upload.Column()
@property
def image_url(self):
return f'{self.__tablename__}/{self.id}/{self.image__file_name}'
with app.app_context():
db.drop_all()
db.create_all()
@app.route('/create', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
my_img = request.files['my-img']
post = Post()
file_upload.save_files(post, files={ 'image': my_img })
db.session.add(post)
db.session.commit()
posts = Post.query.all()
return render_template('create.html', **locals())
@app.route('/media/<path:filename>')
def media(filename):
return send_from_directory(
app.config['UPLOAD_FOLDER'],
filename,
as_attachment=True
)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<input type="file" name="my-img" />
<input type="submit" />
</form>
<div>
{% for post in posts %}
<div><a href="{{ url_for('media', filename=post.image_url) }}">{{post.image__file_name}}</a></div>
{% endfor %}
</div>
</body>
</html>
uj5u.com熱心網友回復:
解決方案:看到 send_from_directory() 檔案字串我明白了!我們不需要path_list,path_和file_name變數。使用 Flask 提供媒體檔案的正確方法是:
@app.get('/media/<path:path>')
def send_media(path):
"""
:param path: a path like "posts/<int:post_id>/<filename>"
"""
return send_from_directory(
directory=app.config['UPLOAD_FOLDER'], path=path
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/343845.html
