title: Retrieving user-uploaded images from filesystem for display in Flask template
body: <p>I'm wiring up a website which allows my client to create a item listing, then upload images of the item. What I need is a way of associating the images with their respective metadata. After extensive StackOverflow browsing and Google-fu, I've yet to come across a specific solution, only vague references that filesystem storage is better than BLOB storage.</p>
  
  <p>So, as it stands, I naturally have a <code>User</code> object and a <code>Listing</code> object which can have several associated images, including a "default" image. Listing has a handful of attributes like <code>listing.id</code>, <code>listing.title</code>, <code>listing.body</code>, etc.</p>
  
  <p>Some info: I'm using Python (Flask), Postgresql, and SQLAlchemy.</p>
  
  <h2>My initial approach.</h2>
  
  <p>I started off with the idea that I would upload the image files to Flask's static directory, with the basic structure of:</p>
  
  <pre><code>static/
    images/
      category_1/
        listing_1/           # based on the DB id
          default.jpg        # renamed server-side to represent default view of item
          random_string.jpg  # renamed to avoid naming collisions
          random_string.gif  # renamed to avoid naming collisions
        listing_2/
          default.jpg
          random_string.png
      category_2/
        # etc.
  </code></pre>
  
  <p>This way I could simply construct the path to the file based the <code>listing.id</code>. This has a problem though: I've allowed the extensions <code>.png</code>, <code>jpg</code>, <code>.jpeg</code>, and <code>.gif</code>. To display the default representation in a template, then, something like a</p>
  
  <pre><code>glob.glob(os.path.join(app.config['UPLOAD_FOLDER'], listing.category, str(listing.id), 'default*'))
  </code></pre>
  
  <p>or a convoluted <code>if/elif/elif/else</code> is necessary. That means something like (pseudocode):</p>
  
  <pre><code>for listing in listings:
    ext = rsplit_of_glob(listing.id)
    listing.ext = ext
  </code></pre>
  
  <p>And now things start to look murkier. Which leads me to</p>
  
  <h2>My second approach.</h2>
  
  <p>I could keep the same directory structure (unless anyone has any objections), but store the paths to the images as a list in the database. It would solve any problems with errant extensions or some future off-by-one problem I can't see right now.</p>
  
  <p>Unfortunately, if I store the full path, it introduces the problem that now everything will be hardcoded. I was trying to avoid that. So my compromise is to add an images column in each <code>listing</code> row in the database, but only include the images' filenames + extensions. This way I can create the path based on the <code>listing.id</code>, and still have all the requisite information.</p>
  
  <h2>The real question.</h2>
  
  <p>Is either of these solutions on the right path, or am I missing something entirely? Forgive my naiveté. I'd also like to know what the best way of storing image-specific metadata (e.g., upload timestamp) for each image is. Something tells me creating an image table/SQLAlchemy image object is overkill. Would a storing a pickled Python dictionary of metadata in each <code>listing</code> row suffice?</p>
  
  <p>I realize this is a large question, and possibly subject to being closed for its somewhat open-ended nature, but any help would be appreciated. There may be no canonical answer, but something tells me there has to be a best-practices way of doing this.</p>
  
  <p>Thanks.</p>