So what I did is that I tried to run my flask app but suddenly I got a error which is TypeError: storage must be a werkzeug.FileStorage
This is the code that I use...
init.py
# IMPORT
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_uploads import UploadSet, configure_uploads, IMAGES, patch_request_class
from blogapp.config import Config
# INIT
db = SQLAlchemy()
bcrypt = Bcrypt()
login_manager = LoginManager()
migrate = Migrate()
login_manager.login_view = 'users.login'
login_manager.login_message_category = 'info'
photos = UploadSet('photos', IMAGES)
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
bcrypt.init_app(app)
login_manager.init_app(app)
migrate.init_app(app, db)
configure_uploads(app, photos)
patch_request_class(app)
from blogapp.users.routes import users
from blogapp.posts.routes import posts
from blogapp.main.routes import main
from blogapp.errors.handlers import errors
app.register_blueprint(users)
app.register_blueprint(posts)
app.register_blueprint(main)
app.register_blueprint(errors)
return app
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY')
SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI')
UPLOADED_PHOTOS_DEST = os.path.join(basedir, 'uploads')
I have a uploads folder in my parent directory
routes.py
from flask import (render_template, url_for, flash,
redirect, request, abort, Blueprint)
from flask_login import current_user, login_required
from blogapp import db, photos
from blogapp.models import Post
from blogapp.posts.forms import PostForm
posts = Blueprint('posts', __name__)
@posts.route("/post/new", methods=['GET', 'POST'])
@login_required
def new_post():
form = PostForm()
if form.validate_on_submit():
filename = photos.save(form.photo.data)
file_url = photos.url(filename)
else:
file_url = None
if form.validate_on_submit():
post = Post(title=form.title.data, content=form.content.data, image=form.photo.data, author=current_user)
db.session.add(post)
db.session.commit()
flash('Your post has been created!', 'success')
return redirect(url_for('main.home'))
return render_template('create_post.html', title='New Post',
form=form, file_url=file_url, legend="Post")
Can someone help me? I'm a bit confuse with how I got the error.. Did I do something wrong?
There isn't any thing I could find out there, so for me this is very confusing.. Could it be something wrong with the application factory while using flask upload?
When I have a look at your routes.py
, I see some possible problems.
new_post
does accept both get and post requests, but does not handle them differently.
e.g. usually when there is a get request, you want to just render the empty form, but when there is a post request, you want to e.g. save the file.
You have two if form.validate_on_submit
statements. You can simplify them when you move the else to the bottom, just above the return statement. Actually, you do not need an else path as, when the if path is valid, you leave the function with the return redirect
already.
About your problem.
The error message clearly says, that form.photo.data
is no uploaded file.
Please fix the above suggestions and try it again.
Also make sure you do not send an empty form. Btw - you did not show your form template. Maybe there is no data
field?
If you followed all suggestions, but without success, please set a breakpoint just after e.g. form = PostForm()
and carefully step through your program and especially inspect what value form.photo.data shows.