在Flask的视图函数中,如何处理文件过大导致的异常?
我想在我的视图中捕获RequestEntityTooLarge,但我的自定义错误处理程序却被调用。
我的 "movie.py" 有一个用于创建新电影条目的路由。
from flask import (
Blueprint, render_template, request, flash, redirect, url_for, current_app
)
from datetime import datetime
from flask_login import login_required
from moviedb.shared.models import db
from moviedb.movies.models import Movie
from sqlalchemy.exc import IntegrityError
from moviedb.shared.utils import upload_file, delete_old_file
from werkzeug.exceptions import RequestEntityTooLarge
bp = Blueprint('movie', __name__)
@bp.route('/create', methods=('GET', 'POST'))
@login_required
def create():
if request.method == 'POST':
request.max_content_length = current_app.config['MAX_UPLOAD_SIZE']
title = request.form['title']
subtitle = request.form['subtitle']
description = request.form['description']
author = request.form['author']
release = request.form['release']
error = None
new_filename = None
if not title:
error = {'movie_create_invalid_title' : 'Title is required.' }
if not subtitle:
error = {'movie_create_invalid_subtitle': 'Subtitle is required.' }
if not description:
error = {'movie_create_invalid_description': 'Description is required.' }
if not author:
error = {'movie_create_invalid_author': 'Author is required.' }
if not release:
error = {'movie_create_invalid_release': 'Release is required.' }
existing_movie = db.session.execute(db.select(Movie).where(Movie.title == title)).scalar()
if existing_movie is not None:
error = {'movie_create_movie_already_exists': f'The movie with the title {title} already exists.' }
if error is not None:
flash(error)
else:
try:
new_filename = upload_file(request, 'image')
release_date = datetime.strptime(release, '%Y-%m-%d')
movie = Movie(title=title,
subtitle=subtitle,
description=description,
author=author,
release=release_date,
image=new_filename)
db.session.add(movie)
db.session.commit()
except ValueError as e:
db.session.rollback()
error = { 'movie_create_value_error' : f'A value error occured. {e}' }
except IntegrityError as e:
db.session.rollback()
error = { 'movie_create_integrity_error' : f"A integrity error occured. {e.code}" }
except RequestEntityTooLarge as e:
db.session.rollback()
error = { 'movie_create_request_entity_too_large' : f"The file is too large for upload. {e.code}"}
else:
return redirect(url_for('movie.index'))
if error is not None:
flash(error)
return render_template('movie/create.html')
我的 "init.py" 把一切拼在一起。
from flask import Flask
from moviedb.login import login_manager
from moviedb.shared.models import db
from moviedb import auth, movie, download
from moviedb import error_handlers
def create_app():
app = Flask(__name__)
if app.config['DEBUG']:
app.config.from_object('moviedb.default_settings')
else:
app.config.from_envvar('MOVIEDB_SETTINGS')
app.register_error_handler(404, error_handlers.page_not_found)
app.register_error_handler(405, error_handlers.method_not_allowed)
app.register_error_handler(413, error_handlers.request_entity_too_large)
login_manager.init_app(app)
db.init_app(app)
with app.app_context():
db.create_all()
app.register_blueprint(auth.bp)
app.register_blueprint(movie.bp)
app.add_url_rule('/', endpoint='index')
app.register_blueprint(download.bp)
app.add_url_rule('/uploads/<name>', endpoint="download_file", build_only=True)
return app
if __name__ == '__main__':
create_app()
我的 "error_handlers.py" 用来处理错误。
from flask import render_template
def page_not_found(e):
return render_template('404.html'), 404
def method_not_allowed(e):
return render_template('405.html'), 405
def request_entity_too_large(e):
return render_template('413.html'), 413
我想要实现的是,在上传的文件太大时显示错误信息。
我该如何正确地实现呢?
解决方案
我通过这篇帖子找到了一个解决方案:
https://stackoverflow.com/a/23601025/26749427
我只是把下面这段代码加到了我的upload_file函数中:
file.seek(0, os.SEEK_END)
file_size = file.tell()
file.seek(0, os.SEEK_SET)
if file_size > current_app.config['MAX_UPLOAD_SIZE']:
raise RequestEntityTooLarge()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。