Contents

0. Project Structure 1. Database 2. Flask Backend 3. JavaScript API 4. HTML / Jinja 5. Testing 6. Complete Data Flow

Back

Fullstack Flask Example - Burger Shop

From Database to Frontend with JS and Jinja Templates

0️⃣ Project Structure → Files & Folders

Before diving into code, here’s how the project is organized:

    burger_shop/
    │
    ├── app/
    │   ├── __init__.py
    │   ├── models.py          # Database models (SQLAlchemy / Django ORM)
    │   ├── views.py           # Routes / Views
    │   ├── templates/         # HTML + Jinja/Django templates
    │   │   └── index.html
    │   └── static/            # CSS / JS files
    │       ├── css/
    │       └── js/
    │
    ├── requirements.txt       # Dependencies
    └── run.py / manage.py     # Entry point
      

This folder structure keeps models, routes, templates, and static files organized for a clean fullstack app.

1️⃣ Database → Models (Python / SQLAlchemy)

We define the tables for burgers and cart items using SQLAlchemy:

        # Python model for burgers
        class Burger(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(120), nullable=False)
        price = db.Column(db.Numeric(6,2), nullable=False)

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'price': float(self.price)
        }
  

Each row in the database can now be converted to JSON with to_dict().

2️⃣ Flask Backend → Routes / Blueprints

Example route to return all burgers as JSON:

@bp.route(''/burgers/api'', methods=['GET'])
def api_list():
    burgers = Burger.query.all()          # Query all burgers from database
    return jsonify([b.to_dict() for b in burgers])  # Return as JSON
  

Flask receives the GET request, queries the database, and sends JSON that JS can fetch.

3️⃣ JavaScript → API Consumption

Example function to add items to the cart:

async function addToCart(burgerId, qty = 1) {
  const res = await fetch('/cart/api', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({burger_id: burgerId, quantity: qty})
  });
  return res.json();
}
  

JS sends JSON data to the backend, which updates the cart and returns a JSON response.

4️⃣ HTML / Jinja → Initial Render

Template example using Jinja to display burgers:

<ul id="catalog">
  {% for b in burgers %}
    <li>
      <strong>{{ b.name }}</strong> — ${{ '%.2f'|format(b.price) }}
      <button class="add-to-cart" data-id={{ b.id }}>Add</button>
    </li>
  {% endfor %}
</ul>
  

Jinja renders HTML dynamically using data Flask passes from the database.

5️⃣ Testing → Python & JS

Example of testing Python model and JS function:

# Python test for Burger model
def test_burger_to_dict():
    b = Burger(name='Cheese', price=5.99)
    assert b.to_dict() == {'id': None, 'name': 'Cheese', 'price': 5.99}

// JS test for addToCart function
async function testAddToCart() {
  res = await addToCart(1, 2);
  console.log('Cart response:', res);
}
  

6️⃣ Complete Data Flow

Layer Example Purpose
Database burgers table Stores burger items and cart entries
Python Models Burger.query.all() Queries database and returns objects
Flask Backend /burgers/api Handles JSON API & cart actions
Frontend JS fetch('/cart/api') Sends requests and updates UI dynamically
HTML / Jinja {{ '{{ b.name }}' }} Renders initial data and buttons
Testing Python: test_burger_to_dict()
JS: testAddToCart()
Ensures backend and frontend logic works