I can see the frontend form though, but if I try to submit the console would show: "Fetch API cannot load http://localhost:8000/api/task-create/ due to access control checks." and the next line is: "Failed to load resource: Cannot establish connection with the server."
This is what I see on my PC, (no problem with this every function works perfectly)

And this is what I get on a different PC connected to the same LAN

I think it has something to do with headers and CORS, Django REST Framework Authentication, I have tried it all but it doesn't seem to work.
Any hints?
This is my settings.py:
Django settings for todoapp project.
Generated by 'django-admin startproject' using Django 3.2.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-whh5g$8**@u4t1m%13=c$6!k-5#o0jwhr&&7i7^d$ky%$ku+ls'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'api.apps.ApiConfig'
]
MIDDLEWARE = [
'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',
'corsheaders.middleware.CorsMiddleware',
]
ROOT_URLCONF = 'todoapp.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'frontend/build')
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'todoapp.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'frontend/build/static')
]
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
CORS_ALLOWED_ORIGINS = [
"http://192.168.0.6:3000",
]
my views.py:
from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.decorators import api_view
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from .serializers import TaskSerializer
from .models import Task
# Create your views here.
@api_view(['GET'])
def apiOverview(request):
api_urls = {
'List':'task-list/',
'Detail View':'/task-detail/<str:pk>',
'Create':'/task-create/',
'Update':'task-update/<str:pk>',
'Delete':'task-delete/<str:pk>',
}
return Response(api_urls)
@api_view(['GET'])
def taskList(request):
tasks = Task.objects.all()
serializer = TaskSerializer(tasks, many=True)
return Response(serializer.data)
@api_view(['GET'])
def taskDetail(request, id):
task = Task.objects.get(id=id)
serializer = TaskSerializer(task, many=False)
return Response(serializer.data)
@api_view(['POST'])
def taskCreate(request):
serializer = TaskSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['POST'])
def taskUpdate(request, id):
task = Task.objects.get(id=id)
serializer = TaskSerializer(instance=task, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['DELETE'])
def taskDelete(request, id):
task = Task.objects.get(id=id)
task.delete()
return Response('Task succesfully deleted!')
and my react main component App.js:
import React from "react"
import './App.css';
import TodoItem from "./TodoItem"
import Form from "./Form"
class App extends React.Component {
constructor(props){
super(props)
this.state = {
todoList:[],
activeItem:{
id:null,
title:'',
completed:false,
},
editing:false,
}
this.fetchTasks = this.fetchTasks.bind(this)
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.getCookie = this.getCookie.bind(this)
this.handleEdit = this.handleEdit.bind(this)
this.handleDelete = this.handleDelete.bind(this)
this.handleCompleted = this.handleCompleted.bind(this)
}
getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
componentDidMount(){
this.fetchTasks()
}
fetchTasks(){
fetch('http://localhost:8000/api/task-list/')
.then(response => response.json())
.then(data =>
this.setState({
todoList: data
})
)
}
handleChange(event){
let value = event.target.value
this.setState({
activeItem: {
...this.state.activeItem,
title: value
}
})
}
handleSubmit(event){
event.preventDefault()
let csrftoken = this.getCookie('csrftoken')
let url='http://localhost:8000/api/task-create/'
if(this.state.editing === true){
url=`http://localhost:8000/api/task-update/${this.state.activeItem.id}/`
this.setState({
editing: false
})
}
fetch(url,{
method: 'POST',
headers:{
'Content-type':'application/json',
'X-CSRFToken': csrftoken,
},
body: JSON.stringify(this.state.activeItem)
}).then(()=>{
this.fetchTasks()
this.setState({
activeItem:{
id:null,
title:'',
completed:false,
}
})
}).catch((e)=>{
console.log('ERROR:',e)
})
}
handleEdit(todo){
this.setState({
activeItem: todo,
editing: true,
})
}
handleDelete(todo){
let csrftoken = this.getCookie('csrftoken')
let url = `http://localhost:8000/api/task-delete/${todo.id}/`
fetch(url, {
method: 'DELETE',
headers: {
'Content-type': 'application/json',
'X-CSRFToken': csrftoken
}
}).then((response)=>{
this.fetchTasks()
}).catch((error)=>{
console.log('ERROR:',error)
})
}
handleCompleted(todo){
let csrftoken = this.getCookie('csrftoken')
const url=`http://localhost:8000/api/task-update/${todo.id}/`
todo.completed= !todo.completed
fetch(url,{
method:'POST',
headers:{
'Content-type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
title:todo.title,
completed:todo.completed,})
}).then(()=>{
this.fetchTasks()
}).catch((e)=>{
console.log('ERROR:',e)
})
}
render(){
let todoItems = this.state.todoList.map((todo, id)=>{
return(
<TodoItem
key={id} todo={todo}
onClick={()=> this.handleEdit(todo)}
onDelete={()=> this.handleDelete(todo)}
onCompleted={()=> this.handleCompleted(todo)}
/>
)
})
return(
<div className="container">
<div id="task-container">
<Form
onChange={this.handleChange}
onSubmit={this.handleSubmit}
data={this.state.activeItem}
/>
<div id="list-wrapper">
{todoItems}
</div>
</div>
</div>
)
}
}
export default App;
Thanks for the help in adavnce...
You might having issue with the ip address. Like, this different computer might have an activated VPN or any other issue that points to other ip adress not a localhost.
So, in your django
settings.pytry to change this:to this approach:
Or if you want to allow all:
And check if it works.