简体   繁体   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. 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. But the problem is I want to change the state of "completed" to depict a task completed.但问题是我想更改“已完成”的 state 来描述任务已完成。 Im trying to do this by sending a PUT request to the API using the unique "id" but getting some errors.我试图通过使用唯一的“id”向 API 发送 PUT 请求来做到这一点,但出现了一些错误。 Below is my approach:以下是我的方法:

List.js 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 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;

views.py of API 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)

The DELETE method works well, but I'm not getting any idea about how to do it for PUT/POST. DELETE 方法效果很好,但我不知道如何为 PUT/POST 执行此操作。 Went through many resources but most of them were suggesting axios which I don't want to use now.浏览了许多资源,但其中大多数都建议我现在不想使用axios I want to get this done using fetch() .我想使用fetch()来完成这项工作。

When I use body:JSON.stringify(this.state.todos) I get the error below:当我使用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

When I use body:JSON.stringify(this.state) I get the error below:当我使用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

What to do now?现在要做什么?

( Note: To test it locally, clone this git repository ) 注意:要在本地测试它,请克隆git 存储库

Please try to use PATCH instead of PUT .请尝试使用PATCH而不是PUT

  • PUT is for full object update, PUT用于完整的 object 更新,
  • PATCH is for partial update (you can update only selected field). PATCH用于部分更新(您只能更新选定的字段)。

What you need is PATCH .你需要的是PATCH

In the update request, please send only the dict with the field that you want to update ({"status": "complete"}) and set id in the request URL.在更新请求中,请仅发送带有您要更新的字段的dict({“status”:“complete”})并在请求URL中设置id

What is more, you can check the full working CRUD example in my article: CRUD in Django Rest Framework and React .更重要的是,您可以在我的文章中查看完整的工作 CRUD 示例: Django Rest Framework 和 React 中的 CRUD

remove?format=json.删除?格式=json。 Don't forget to add trailing forward slash after id!不要忘记在 id 之后添加斜杠!

Before

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

After

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