Requests to the Django API from React are not allowed

Viewed 309

I was introduced to web development using React and Django. As a tutorial, I was creating a to-do application. When I sent an API request from React, it was marked as Not Allowed. However, when I send the same request from curl, it is allowed. It seems that the API side is not set up properly.

The code in question is shown below.

import React, { useState } from "react";
import {CustomModal} from "./components/Modal";
import axios from "axios";


function App() {
  const [isComplete, setComplete] = useState(true);
  const [modal, setModal] = useState(false);
  const [todoItems, setToDoItems] = useState([]);

  const handleSubmit = (item) => {
    setModal(!modal);
    if (item.id) {
      axios
      .put(`http://localhost:8000/api/todos/${item.id}/`, item)
      .then(res => refreshList);
    } else {
      axios
        .put(`http://localhost:8000/api/todos/`, item)
        .then(res => refreshList);
    }
  };

  const handleDelete = (item) => {
    axios
    .post(`http://localhost:8000/api/todos/${item.id}`, item)
    .then(res => refreshList);
  };

  const [Item, setItem] = useState({title: "", description: "", completed: false });
  const createItem = () => {
    const item = { title: "", description: "", completed: false };
    setItem(item);
    setModal(!modal);
  };

  const editItem = ( item ) => {
    setItem(item);
    setModal(!modal);
  };

  const refreshList = () => {
    axios
      .get("http://localhost:8000/api/todos/")
      .then(res => setToDoItems(res.data))
      .catch(err => console.log(err));
  };

  const displayCompleted = (status) => {
    if (status) {
      setComplete(true);
    }
      setComplete(false);
  };

  const renderTabList = () => {
    return (
      <div className="my-5 tab-list">
        <span
          onClick={() => displayCompleted(true)}
          className={isComplete ? "active" : ""}
        >
          complete
        </span>
        <span onClick={() => displayCompleted(false)}
              className={isComplete ? "" : "active"}
        >
          Incomplete
        </span>
      </div>
    );
  };

  const renderItems = () => {
    const items = todoItems.filter(item => item.completed === isComplete);
    return items.map(item => (
      <li key={ item.id } className="list-group-item d-flex justify-content-between align-items-center">
        <span 
          className={`todo-title mr-2 ${
                isComplete ? "completed-todo" : ""
              }`}
          title={item.description}
        >
          {item.title}
        </span>
        <span>
          <button onClick={() => editItem(item)} className="btn btn-secondary mr-2"> Edit </button>
          <button onClick={() => handleDelete(item)} className="btn btn-danger"> Delete </button>
        </span>
      </li>
    ));
  };

  return (
    <main>
      <h1 className="text-white text-uppercase text-center my-4">To Do App</h1>
      <div className="row ">
        <div className="col-md-6 col-sm-10 mx-auto p-0">
          <div className="card p-3">
            <div className="">
              <button onClick={createItem} className="btn btn-primary">Add task</button>
            </div>
            { renderTabList() }
            <ul className="list-group list-group-flush">
              {renderItems()}
            </ul>
          </div>
        </div>
      </div>
      {modal ? (
        <CustomModal
          activeItem={Item}
          toggle={setModal}
          onSave={handleSubmit}
        />
      ) : null}
    </main>
  );
}

export default App;

Also, the backend/setting.py file

# ...omission
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',
    'rest_framework',
    'todo',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# ...omission


# we whitelist localhost:3000 because that's where frontend will be served
CORS_ORIGIN_WHITELIST = [
    'http://localhost:3000',
]
CORS_ORIGIN_ALLOW = True

The error in the Developer Tools is as follows

PUT http://localhost:8000/api/todos/ 405 (Method Not Allowed)
dispatchXhrRequest  @   xhr.js:177
xhrAdapter  @   xhr.js:13
dispatchRequest @   dispatchRequest.js:52
Promise.then (async)        
request @   Axios.js:61
Axios.<computed>    @   Axios.js:87
wrap    @   bind.js:9
handleSubmit    @   App.js:18
onClick @   Modal.js:68
onClick @   Button.js:50
callCallback    @   react-dom.development.js:3945
invokeGuardedCallbackDev    @   react-dom.development.js:3994
invokeGuardedCallback   @   react-dom.development.js:4056
invokeGuardedCallbackAndCatchFirstError @   react-dom.development.js:4070
executeDispatch @   react-dom.development.js:8243
processDispatchQueueItemsInOrder    @   react-dom.development.js:8275
processDispatchQueue    @   react-dom.development.js:8288
dispatchEventsForPlugins    @   react-dom.development.js:8299
(anonymous) @   react-dom.development.js:8508
batchedEventUpdates$1   @   react-dom.development.js:22396
batchedEventUpdates @   react-dom.development.js:3745
dispatchEventForPluginEventSystem   @   react-dom.development.js:8507
attemptToDispatchEvent  @   react-dom.development.js:6005
dispatchEvent   @   react-dom.development.js:5924
unstable_runWithPriority    @   scheduler.development.js:646
runWithPriority$1   @   react-dom.development.js:11276
discreteUpdates$1   @   react-dom.development.js:22413
discreteUpdates @   react-dom.development.js:3756
dispatchDiscreteEvent   @   react-dom.development.js:5889
Uncaught (in promise) Error: Request failed with status code 405
    at createError (createError.js:16)
    at settle (settle.js:17)
    at XMLHttpRequest.handleLoad (xhr.js:62)
0 Answers
Related