Skip to content

Create - Sending Data

You know GET fetches data. POST sends data. Now let's wire up a form so that clicking a button sends a new patient to Flask, Flask saves it to PookieDB, and the table updates - all without reloading the page.


What travels in a POST request

When you send a GET request, the URL carries everything the server needs. When you send a POST request, the data travels in the request body - a separate part of the request that is not visible in the URL.

The body is always a string. To send a JavaScript object as the body, you convert it to a JSON string first using JSON.stringify():

let data = { name: "Alice", age: 24 }

JSON.stringify(data)
// '{"name":"Alice","age":24}'

That string is what travels over the network.


Telling Flask the body is JSON

When Flask receives a request, it does not automatically know what format the body is in. You tell it by setting the Content-Type header:

headers: { "Content-Type": "application/json" }

This tells Flask: "the body is a JSON string, please parse it for me."

On the Flask side, request.get_json() reads the body and converts it back to a Python dictionary.


The complete flow

JavaScript - the form and the fetch call:

function addPatient() {
  let name = document.getElementById("name").value
  let age  = document.getElementById("age").value

  fetch("/patients", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name: name, age: parseInt(age) })
  })
    .then(response => response.json())
    .then(result => {
      console.log("Saved with id:", result.id)
      loadPatients()
    })
    .catch(error => console.log("Error:", error))
}

Flask - the route that receives the POST:

@app.route('/patients', methods=['POST'])
def add_patient():
    data = request.get_json()
    patient = Patient.objects.create(
        name=data["name"],
        age=data["age"]
    )
    return jsonify({ "status": "ok", "id": str(patient.id) })

str(patient.id) converts the UUID object to a string so it can travel in JSON.


The complete project files

database.py

import pookiedb

pookiedb.connect("sqlite:///patients.sqlite3")

class Patient(pookiedb.Model):
    id   = pookiedb.UUIDField(auto=True, primary_key=True)
    name = pookiedb.CharField(max_length=100)
    age  = pookiedb.IntegerField()

    class Meta:
        db_table = "patients"

Patient.create_table()

app.py

from flask import Flask, render_template, request, jsonify
from database import Patient

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html')

@app.route('/patients', methods=['POST'])
def add_patient():
    data = request.get_json()
    patient = Patient.objects.create(name=data["name"], age=data["age"])
    return jsonify({ "status": "ok", "id": str(patient.id) })

if __name__ == '__main__':
    app.run(debug=True)

templates/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Patients</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
    <div class="container mt-4">

      <h1 class="mb-4">Patients</h1>

      <div class="mb-3">
        <input id="name" type="text" class="form-control mb-2" placeholder="Name">
        <input id="age"  type="number" class="form-control mb-2" placeholder="Age">
        <button onclick="addPatient()" class="btn btn-primary">Add Patient</button>
      </div>

      <table class="table table-striped">
        <thead><tr><th>Name</th><th>Age</th></tr></thead>
        <tbody id="patient-rows"></tbody>
      </table>

    </div>

    <script>
      function addPatient() {
        let name = document.getElementById("name").value
        let age  = document.getElementById("age").value

        fetch("/patients", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ name: name, age: parseInt(age) })
        })
          .then(response => response.json())
          .then(result => {
            console.log("Saved with id:", result.id)
            loadPatients()
          })
          .catch(error => console.log("Error:", error))
      }

      function loadPatients() {
        // we will fill this in on the next page
      }
    </script>
  </body>
</html>

Challenge

Set up the project exactly as shown. Run it, add a patient, and check the browser console. You should see "Saved with id:" followed by a UUID. Then stop Flask, restart it, and check whether the patient is still in the database.


← PookieDB Refresher    Next: Read - Getting Data Back →