Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask and sqlalchemy: Get uploaded file using path stored on database

I'm using flask and sqlalchemy and I'm having issues regarding file uploading.

I'm uploading the file with a form and storing the URL to the DB, so I can display it inside on the page.

Here's the form's code:

        boxart = request.files['boxart']

        if boxart:
            filename = secure_filename(boxart.filename)
            boxart_path = os.path.join(app.config['UPLOAD_FOLDER']+"boxart/", filename)
            boxart.save(boxart_path)
            game_son.boxart = boxart_path

        db.session.add(game_son)
        db.session.commit()

So I go to my template and I can print the content of game_son.boxart and there is the full path to the file. If I click on the link, I can access, but the image will not display inside tag...

I tried getting it on the template by using:

    <img src="{{ game_son.boxart_url() }}" />

Inside the model, I defined a boxart_url method, in case I need to parse the string before sending it

  class Game_son(db.Model):
    __searchable__ = ['version_name']
    son_id = db.Column(db.Integer, primary_key=True)
    version_name = db.Column(db.String(128), index=True, unique=False)
    son_timestamp = db.Column(db.DateTime)
    dad = db.Column(db.Integer, db.ForeignKey('game_dad.id'))
    console = db.Column(db.Integer, db.ForeignKey('platform.id'))
    boxart = db.Column(db.String(256))
    thumbnail = db.Column(db.String(256))
    genre = db.Column(db.String(32))
    subgenre = db.Column(db.String(32))

    def boxart_url(self):
        return self.boxart 

    def __repr__(self):
        return '<Game %r>: %r' % (self.version_name, self.dad)

The page's view just send the entire object (game) to the page.

The url that is arriving on the page is:

/home/removed_my_pc_user/app/media/boxart/image.jpg

Edit: I just remembered that I'm using a virtual environment on the project.

Is it related to chmod?

Thanks in advance!!

like image 747
Felipe Avatar asked May 14 '15 12:05

Felipe


Video Answer


1 Answers

Well, It's strange but I will answer my own question.

The solution is simple, I chose to store only the file names inside the database.

Then I created a route to a view that will return the file using the send_from_directory function from flask.ext.uploads

@app.route('/boxart/<filename>')
    def uploaded_boxart(filename):
        return send_from_directory(app.config['UPLOAD_FOLDER'],filename)

So, inside the template we can use the url_for() function to load the file, sending as a parameter the filename stored inside the database.

<img src="{{ url_for('uploaded_boxart', filename = game_son.boxart)}}" />

Also, I think that one of my mistakes was putting the media/ folder inside the app/ folder, and not inside the root directory. So I also reconfigured the UPLOAD_FOLDER in app.config.

like image 183
Felipe Avatar answered Nov 05 '22 17:11

Felipe