FastAPI - использование JQuery - AJAX - метод PUT не работает

Добрый день. Я изучаю FastAPI и делаю очень простое приложение CRUD, используя Javascript во внешнем интерфейсе и FastAPI в качестве бэкенда. Все маршруты работают с использованием обычных документов localhost / docs swagger. Я использую jquery и AJAX во внешнем интерфейсе.

У меня подключена база данных postgresql

Пока что метод POST работает нормально - обновляет базу данных и отображается во внешнем интерфейсе.

Я создал 2 блока формы: 1 - для метода создания (POST) - отлично работает - myForm 2 - для метода обновления (PUT) - не работает - updateForm (статическое без переключения и т. Д.)

Логика внешнего интерфейса заключается в том, что когда я нажимаю кнопку редактирования (используя jquery), я отображаю данные в updateForm - эта часть работает. Поскольку я могу консоль, записывать данные и видеть все, что возвращается.

Однако, когда я хочу опубликовать (т.е. использовать PUT) метод на кнопке «Обновить статью» (при нажатии), сервер отправляет ответ 200 ok, но данные в базе данных не обновляются.

Я был бы признателен за некоторую помощь - занимался этим последние два дня ....

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

person Barnez299    schedule 23.12.2020    source источник
comment
просто чтобы развернуть, это трассировка ошибки, которую я получаю при использовании PUT NFO: 127.0.0.1:55720 - "GET / HTTP/1.1" 200 OK INFO: 127.0.0.1:55720 - "GET /notes/3 HTTP/1.1" 200 OK INFO: 127.0.0.1:55720 - "GET /?update_id=3&updatetitle=title+3&updatedescription=title+3+description HTTP/1.1" 200 OK   -  person Barnez299    schedule 23.12.2020
comment
ко всем просмотру - я все еще не могу решить ... пожалуйста, помогите   -  person Barnez299    schedule 30.12.2020


Ответы (1)


Я думаю, что с кодом, который вы предоставили, есть всего две небольшие проблемы.

Первый

В index.html вы делаете запрос на получение при нажатии кнопки редактирования. Вместо этого вы должны сделать post или put. Вы можете сделать это с помощью type: "post" или поставить соответственно.

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)
                },
            });
        }); 

Второй

В main.py оба маршрута put_note и patch_note ничего не возвращают. Вы хотите вернуть обновленную модель.

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
person awtkns    schedule 03.01.2021