Adding and Storing Images in Flask - tstorrnetnz/teaching2025 GitHub Wiki

Adding & storing images in Flask

There are at least 2 ways of adding images to your Python-Flask project:

  1. Uploading an image to a folder and storing the link/URL to the image in the database (recommended)
  2. Storing the image itself as a binary blob in a class in your database( not recommended but doable)

Storing images in an uploads folder

In this method, images are stored in a dedicated folder and the url (location) of the image stored as a separate field in the database, as part of the person class.

There is a reasonably well commented example of this technique in this github repository and this repl SQLAlchemy Images in a folder.

  1. The person class needs a column adding for the url url = Column("imageURL", String(255))#url of image

  2. The constructor has url added - but we give it a default value of "None" so that we can create people without an image. None is a special type that is 'nothing' - different from "" which is an empty String def __init__(self, ssn, first, last, gender, age, url=None):

  3. We also add a get_url method

    def get_url(self):
    return self.url
    
  4. In the add a person route we need to add code to process an image and create a person including the url

    image = request.files['image']
    image_url = secure_filename(image.filename)
    image.save(os.path.join('static/uploads', image_url))
    
  5. When we add the newly created person, make sure we include the url parameter p = Person(ssn, first_name, last_name, gender, age, image_url)#add image url

  6. Create two folders static and uploads (uploads inside static) Case sensitive!

  7. In the people.html file, we add extra code to loop through any images when we visit the people page.

    Example using a loop below:
    {# Jinja loop, almost like Python #}
    {# set - used to create a variable #}
    {# if is string - is used as not all the url variables have a value #}
    {# {{url}}  is used to access the the url} #}
    {% for result in query_results %}
        <li>{{ result}}</li>
    {% if result.get_url() is string%}
    {% set url =  "/static/uploads/" + result.get_url() %}
    <img src= {{url}} alt="my image" width="120" height="180" />
    {% endif %}
    {% endfor %}
    
  8. The add person page has the image upload html added <input type="file" name="image">

Screenshot from 2023-08-11 15-08-43

Image of folder structure

Screenshot from 2023-08-11 10-51-17

Image button on add_person.

Screenshot from 2023-08-11 10-51-42

Person displayed on the people page

Storing images in the database

The advantages of this method are that you do not have to worry about image URLs or the image being mistakenly deleted. One concern though is database performance - which should not be a problem for our small databases.

There is a reasonably well commented example of this technique in this repl SQLAlchemy Images

Some additional imports are necessary:

from io import BytesIO

from flask import Flask, render_template, request, send_file, Response

from sqlalchemy import create_engine, ForeignKey, Column, String, Integer,CHAR, Text, LargeBinary, update

from werkzeug.utils import secure_filename

The uploaded image is stored in the database as an instance of the Upload class. You may wish to rename this Image class. You could create a one-to-one or one-to-many relationship for associating images with other items in your database. You could also include image captions/alt text as fields for the image. You could even have as image as a direct field in for example a person class. In this example the image is accessed by pointing your browser at the repls URL and adding /download/1 or /download/2 to the URL. The image could easily be passed using the template render technique we have used previously.

Screenshot from 2023-07-28 14-25-33 Screenshot from 2023-07-28 14-26-12 Screenshot from 2023-07-28 14-26-59

⚠️ **GitHub.com Fallback** ⚠️