skip to Main Content

Good day. I am learning FastAPI – and doing a very simple CRUD application – using Javascript in front-end and FastAPI as backend. All routes are working using the normal localhost/docs swagger docs. I am using jquery and AJAX in front end.

I have postgresql database connected

So far the POST method is working fine – updates database and display in front-end.

I have created 2 form divs:
1- for create method (POST) – works fine – myForm
2- for update method (PUT) – not working – updateForm(static no toggling etc)

The logic on front end is when I click on edit button (using jquery) I display the data in the updateForm — this part is working. As I am able to console log the data and see everything returned.

However when I want to post(i.e. use PUT) method on the Update Article button (on click) the server sends a reponse 200 ok – but no data is updated in the database.

I would appreciate some assistance – been at this for past two days….

index.html

{% extends 'layout.html' %} {% include 'header.html' %} {% block title %} Home {% endblock %} {% block body %}
<script type="text/javascript">
    $(document).ready(function() {
        var id;
        var title;
        var description;

        $("#add_button").click(function() {

            title = $("#title").val();
            description = $("#description").val();

            $.ajax({
                url: "/notes",
                type: "post",
                dataType: "json",
                contentType: "application/json",
                data: JSON.stringify({
                    title: title,
                    description: description
                }),

            }).then(setTimeout(location.reload.bind(location), 200));
        });

        $(".edit_button").click(function(id) {

            id = this.id;

            $.ajax({
                url: "/notes/" + id,
                type: "get",
                dataType: "json",
                contentType: "application/json",
                success: function(data) {
                    $($("#updateForm")[0].update_id).val(data.id);
                    $($("#updateForm")[0].updatetitle).val(data.title);
                    $($("#updateForm")[0].updatedescription).val(data.description)

                    console.log(data)

                },

            });
        });
        $(".update_button").click(function(id) {
            id = this.id

            $.ajax({
                url: "/notes/" + id,
                type: "patch",
                dataType: "json",
                contentType: "application/json",
                success: function(data) {
                    console.log("success");
                },

            });
        });
    });
</script>


<div class="container">
    <div class="row">
        <div class="col md-12">
            <div class="jumbotron">
                <form class="row g-3 mb-5 mt-1" id="myForm">
                    <div class="col-4">
                        <label for="title" class="visually-hidden">Article Title</label>
                        <input name="title" type="" class="form-control" id="title" placeholder="title">
                    </div>
                    <div class="col-4">
                        <label for="description" class="visually-hidden">Article Description</label>
                        <input name="description" type="" class="form-control" id="description" placeholder="description">
                    </div>

                    <div class="col-4 mt-2">
                        <button id="add_button" type="submit" class="btn btn-primary mt-4">Add Article</button>
                    </div>

                </form>
                <form class="row g-3 mb-5 mt-1" id="updateForm">
                    <div class="col-3">
                        <label for="updatetitle" class="visually-hidden">ID</label>
                        <input name="update_id" type="" class="form-control update_id" id="update_id">
                    </div>
                    <div class="col-3">
                        <label for="updatetitle" class="visually-hidden">Title</label>
                        <input name="updatetitle" type="" class="form-control updatetitle" id="updatetitle">
                    </div>
                    <div class="col-3">
                        <label for="updatedescription" class="visually-hidden">Description</label>
                        <input name="updatedescription" type="" class="form-control updatedescription" id="updatedescription">
                    </div>

                    <div class="col-3 mt-2">
                        <button id="update_button" type="submit" class="btn btn-primary mt-4" onsubmit="True">Update Article</button>
                    </div>

                </form>


                <table class="table" id="data_table">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>Title</th>
                            <th>Description</th>
                            <th>Action</th>
                        </tr>
                    </thead>
                    <tbody>
                        {%for note in notes%}
                        <tr>
                            <td>{{note.id}}</td>
                            <td>{{note.title}}</td>
                            <td>{{note.description}}</td>
                            <td>
                                <a class="btn btn-warning btn-xs edit_button" id="{{note.id}}">Edit</a>
                                <a class="btn btn-danger btn-xs delete_button" id="{{note.id}}">Delete</a>
                            </td>
                        </tr>
                        {%endfor%}
                    </tbody>

                </table>
            </div>
        </div>
    </div>
</div>




{% endblock %}

main.py

from fastapi import FastAPI
from typing import List, Dict, Any

from fastapi import Depends, FastAPI, HTTPException, Request, Response, Form
from fastapi.encoders import jsonable_encoder
from fastapi.responses import HTMLResponse
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
from fastapi.templating import Jinja2Templates

from . import crud, models, schemas
from .database import SessionLocal, engine

models.Base.metadata.create_all(bind=engine)



app = FastAPI()
templates = Jinja2Templates(directory="templates")

app.add_middleware(
    CORSMiddleware,
    allow_credentials = True,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
)

# Dependency
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


#original function
# @app.get("/notes", response_model=List[schemas.Note])
# def read_notes(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
#     notes = crud.get_notes(db=db, skip=skip, limit=limit)
#     return notes

# STEP 1 - HOMEPAGE DISPLAY ALL DATA FUNCTION - WORKING
@app.get("/", response_class=HTMLResponse)
def read_notes(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    notes = crud.get_notes(db=db, skip=skip, limit=limit)
    return templates.TemplateResponse("index.html", {
        "request": request,
        "notes": notes,
    })


@app.post("/notes", response_model=schemas.Note, status_code=201)
def create_note(note: schemas.NoteCreate, db: Session = Depends(get_db)):
    return crud.create_note(db=db, note=note)



@app.get("/notes/{note_id}", response_model=schemas.Note)
def read_user(note_id: int, db: Session = Depends(get_db)):
    db_note = crud.get_note(db=db, note_id=note_id)
    if db_note is None:
        raise HTTPException(status_code=404, detail="Note not found")
    return db_note


@app.put("/notes/{note_id}", response_model=schemas.Note, status_code=200)
async def put_note(note_id: int, note: schemas.NoteCreate, db: Session = Depends(get_db)):
    db_note = schemas.Note(id = note_id, title= note.title, description=note.description)
    crud.update_note(db=db, note=db_note)

@app.patch("/notes/{note_id}", response_model=schemas.Note, status_code=200)
async def patch_note(note_id: int, note: schemas.NoteCreate, db: Session = Depends(get_db)):
    print(note_id)
    print(note.title)
    print(note.description)
    db_note = schemas.Note(id = note_id, title= note.title, description=note.description)
    crud.update_note(db=db, note=db_note)

@app.delete("/notes/{note_id}", status_code=204)
async def delete_note(note_id: int, db: Session = Depends(get_db)):
    return crud.delete_note(db=db, note_id=note_id)

if __name__ == '__main__':
    uvicorn.run("main:app", host="127.0.0.1", port=8000)

schemas.py

from typing import List, Optional
from pydantic import BaseModel


class NoteBase(BaseModel):
    title: str
    description: str


class NoteCreate(NoteBase):
    pass

class Note(NoteBase):
    id: int

    class Config:
        orm_mode = True

models.py

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import relationship

from .database import Base

class Note(Base):
    __tablename__ = "notes"
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, nullable=True, default="new")
    description = Column(String, nullable=True, default="new")

crud.py

from sqlalchemy.orm import Session

from . import models, schemas


def get_note(db: Session, note_id: int):
    return db.query(models.Note).filter(models.Note.id == note_id).first()

def delete_note(db: Session, note_id: int):
    db_note = db.query(models.Note).filter(models.Note.id == note_id).first()
    db.delete(db_note)
    db.commit()
    return {}

def get_notes(db: Session, skip: int = 0, limit: int = 100):
    return db.query(models.Note).offset(skip).limit(limit).all()


def create_note(db: Session, note: schemas.NoteCreate):
    db_note = models.Note(title=note.title, description=note.description)
    db.add(db_note)
    db.commit()
    db.refresh(db_note)
    return db_note

def update_note(db: Session, note: schemas.Note):
    db_note = db.query(models.Note).filter(models.Note.id == note.id).first()
    db_note.title = note.title
    db_note.description = note.description
    db.commit()
    db.refresh(db_note)
    return db_note

2

Answers


  1. I think there are just two small problems with the code you provided.

    First

    In index.html you are making a get request when the edit button is clicked. You should be making a post or put instead. You can do this with type: "post" or put respectively.

    index.html

    $(".edit_button").click(function(id) {
                id = this.id;
                $.ajax({
                    url: "/notes/" + id,
                    type: "get", //Change this to post or put
                    dataType: "json",
                    contentType: "application/json",
                    success: function(data) {
                        $($("#updateForm")[0].update_id).val(data.id);
                        $($("#updateForm")[0].updatetitle).val(data.title);
                        $($("#updateForm")[0].updatedescription).val(data.description)
                    },
                });
            }); 
    

    Second

    In main.py, both your put_note and patch_note routes are not returning anything. You want to be returning the updated model.

    main.py

    @app.put("/notes/{note_id}", response_model=schemas.Note, status_code=200)
    async def put_note(note_id: int, note: schemas.NoteCreate, db: Session = Depends(get_db)):
        db_note = schemas.Note(id = note_id, title= note.title, description=note.description)
    
        return crud.update_note(db=db, note=db_note) # Added return
    
    @app.patch("/notes/{note_id}", response_model=schemas.Note, status_code=200)
    async def patch_note(note_id: int, note: schemas.NoteCreate, db: Session = Depends(get_db)):
        print(note_id)
        print(note.title)
        print(note.description)
        db_note = schemas.Note(id = note_id, title= note.title, description=note.description)
    
        return crud.update_note(db=db, note=db_note) # Added return
    
    Login or Signup to reply.
  2. The issue is with your ajax call.. Modify the update_button click function from

            $(".update_button").click(function(id) {
            id = this.id
    
            $.ajax({
                url: "/notes/" + id,
                type: "patch",
                dataType: "json",
                contentType: "application/json",
                success: function(data) {
                    console.log("success");
                },
    
            });
        });
    

    to

        $("#update_button").click(function() {
        //        id = this.id
        id = $("#update_id").val();
        updatetitle = $("#updatetitle").val();
        updatedescription = $("#updatedescription").val();
    
        $.ajax({
            url: "/notes/" + id,
            type: "put",
            dataType: "json",
            contentType: "application/json",
            data: JSON.stringify({
                id: id,
                title: updatetitle,
                description: updatedescription
                }),
            success: function(data) {
                console.log("success",data);
            },
            error: function() {
                console.log("error", data);
                alert('error loading from database...');
                }
        });
      });
    

    and it will work..

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search