簡體   English   中英

無法使用 ZFCE39BEF5E4BD9F96C8Z557FZ 方法向 Django REST API 發送 PUT 請求(1)

[英]Unable to send a PUT request to a Django REST API using Reactjs fetch() method

I've recently started learning Reactjs & made a simple Todo react appplication in order to learn it bit-by-bit, step-by-step.The data in this Todo react front-end is coming from a simple Todo Django REST API. 但問題是我想更改“已完成”的 state 來描述任務已完成。 我試圖通過使用唯一的“id”向 API 發送 PUT 請求來做到這一點,但出現了一些錯誤。 以下是我的方法:

List.js

import React from 'react'
import Todo from './Todo'
import Nav from './Nav'


//Class based Component
class List extends React.Component {

    constructor() {
        super()
        this.state = {
            todos: [],
        }
        this.handleChange = this.handleChange.bind(this)
    }

    fetchData() {
        fetch('http://localhost:8000/Todo-api/')
            .then(response => response.json())
            .then((data) => {
                this.setState({
                    todos: data
                });
            });
    }

    componentDidMount() {
        this.fetchData();
    }

    

    handleChange(id) {
        this.setState(prevState => {
            const updatedData = prevState.todos.map(todo => {
                if (todo.id === id) {
                    todo.completed = !todo.completed
                }
                return todo
            })
            return {
                todos: updatedData
            }
        })

        fetch(`http://127.0.0.1:8000/Todo-api/${id}/?format=json/`,
            {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept' : 'application/json',
                
                    // Other possible headers
                },
                body: JSON.stringify(this.state)

            }).then(function (response) {
                return response.json();
            }).then(function (data) {
                console.log("Data is ok", data);
            }).catch(function (ex) {
                console.log("parsing failed", ex);
            });
    }

    currentDate() {
        return new Date().getFullYear();
    }


    render() {
        const Data = this.state.todos.map(details => <Todo key={details.id} det={details} handleChange={this.handleChange} />)

        const someStyle = {
            marginTop: "40px", marginLeft: "100px", marginRight: "100px",
        }
        console.log(this.state.todos)
        return (
            <div>
                <Nav />

                <div className="todo-list box">
                    {Data}
                </div>

                <hr style={someStyle} />

                <p className="text-center" style={{ fontFamily: "Roboto Mono", lineHeight: 0.5 }}>Copyright ©️ {this.currentDate()} Parth Pandya </p>

                <p className="text-center" style={{ fontFamily: "Roboto Mono", fontSize: 10, lineHeight: 0.5 }}>Some rights reserved.</p>
            </div>
        )
    }
}

export default List

Todo.js

import React from 'react'



function Todo(props) {
  const completeStyles = {
    fontStyle: "italic",
    textDecoration: "Line-through",
    color: "gray",
  }

  return (
    <div className="todo-item">
      <input type="checkbox" onChange={() => props.handleChange(props.det.id)} checked={props.det.completed} />
      <p style={props.det.completed ? completeStyles : null}>{props.det.title}</p>
    </div>
  );
}

export default Todo;

API 的views.py

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from .serializers import TodoDataSerializer
from .models import TodoData
# Create your views here.

class Todolist(APIView):
    serializer_class = TodoDataSerializer

    def get(self, request):
        ToDoData = TodoData.objects.all()
        serializer = TodoDataSerializer(ToDoData, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = TodoDataSerializer(data=request.data)
        if(serializer.is_valid()):
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.data, status=status.HTTP_404_BAD_REQUEST)

class TodoDetail(APIView):
    serializer_class = TodoDataSerializer

    def get(self, request, pk):
        ToDoData = TodoData.objects.get(pk=pk)
        serializer = TodoDataSerializer(ToDoData)
        return Response(serializer.data)

    def delete(self, request, pk):
        ToDoData = TodoData.objects.filter(pk=pk)
        ToDoData.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

    def put(self, request, pk):
        snippets = TodoData.objects.get(pk=pk)
        serializer = TodoDataSerializer(snippets, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

DELETE 方法效果很好,但我不知道如何為 PUT/POST 執行此操作。 瀏覽了許多資源,但其中大多數都建議我現在不想使用axios 我想使用fetch()來完成這項工作。

當我使用body:JSON.stringify(this.state.todos)我收到以下錯誤:

PUT http://127.0.0.1:8000/Todo-api/4/ 400 (Bad Request) Data is ok {non_field_errors: Array(1)}non_field_errors: ["Invalid data. Expected a dictionary, but got list."]__proto__: Object

當我使用body:JSON.stringify(this.state)我收到以下錯誤:

PUT http://127.0.0.1:8000/Todo-api/4/ 400 (Bad Request) Data is ok {title: Array(1), completed: Array(1)} completed: ["This field is required."] title: ["This field is required."] __proto__: Object

現在要做什么?

注意:要在本地測試它,請克隆git 存儲庫

請嘗試使用PATCH而不是PUT

  • PUT用於完整的 object 更新,
  • PATCH用於部分更新(您只能更新選定的字段)。

你需要的是PATCH

在更新請求中,請僅發送帶有您要更新的字段的dict({“status”:“complete”})並在請求URL中設置id

更重要的是,您可以在我的文章中查看完整的工作 CRUD 示例: Django Rest Framework 和 React 中的 CRUD

刪除?格式=json。 不要忘記在 id 之后添加斜杠!

 fetch(`http://127.0.0.1:8000/Todo-api/${id}/?format=json/`, {
      method: "PUT"
      ...
    })

fetch(`http://127.0.0.1:8000/Todo-api/${id}/`, {
          method: "PUT"
          ...
        })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM