Building a TODO App with Python and React
This tutorial will guide you on how to build a simple To-Do application using Python and React. We will be using Python's Django framework for the backend and React for the frontend.
Prerequisites
To follow this tutorial, you should have:
- Basic knowledge of Python and JavaScript.
- Node.js and npm installed on your machine.
- Python 3.8 or newer installed on your machine.
- Django installed in your Python environment.
- An Integrated Development Environment (IDE) like Visual Studio Code.
Let's start!
Backend Setup (Python with Django)
Step 1: Setup a new Django project
In your terminal, navigate to the location where you want your project to be, and run the following commands:
django-admin startproject todo
cd todo
This will create a new Django project named 'todo'.
Step 2: Create a new Django app
Next, create a new Django application within your project.
python manage.py startapp tasks
This will create a new Django application named 'tasks'.
Step 3: Define your models
In tasks/models.py
, define your Task model:
from django.db import models
class Task(models.Model):
title = models.CharField(max_length=200)
completed = models.BooleanField(default=False)
def __str__(self):
return self.title
After defining the model, apply the migrations by running:
python manage.py makemigrations
python manage.py migrate
Step 4: Create a Serializer
To convert complex datatypes, such as querysets and model instances, to native Python datatypes that can then be easily rendered into JSON, XML or other content types, we use Serializers.
In tasks/serializers.py
, write the following code:
from rest_framework import serializers
from .models import Task
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = ('id', 'title', 'completed')
Step 5: Define your Views
In tasks/views.py
, write the following code:
from django.shortcuts import render
from rest_framework import viewsets
from .models import Task
from .serializers import TaskSerializer
class TaskView(viewsets.ModelViewSet):
serializer_class = TaskSerializer
queryset = Task.objects.all()
Step 6: Define your URLs
In tasks/urls.py
, write the following code:
from django.urls import path
from .views import TaskView
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'', TaskView, basename='tasks')
urlpatterns = router.urls
Finally, include the tasks
URLs in the project's URL configuration. In todo/urls.py
:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('tasks.urls')),
]
Frontend Setup (React)
Step 1: Create a new React app
In your terminal, navigate to the location where you want your project to be, and run the following command:
npx create-react-app todo-frontend
cd todo-frontend
Step 2: Install necessary dependencies
We are going to use Axios for HTTP requests and Bootstrap for styling.
npm install axios react-bootstrap bootstrap
Step 3: Create a new component for displaying tasks
Create a new file Tasks.js
in the src
directory and write the following code:
import React, { Component } from 'react';
import axios from 'axios';
class Tasks extends Component {
constructor() {
super();
this.state = {
tasks: []
};
}
componentDidMount() {
this.getTasks();
}
getTasks() {
axios.get('/api/')
.then(res => {
this.setState({ tasks: res.data });
})
.catch(err => {
console.log(err);
});
}
render() {
return (
<div>
{this.state.tasks.map(item => (
<h1 key={item.id}>{item.title}</h1>
))}
</div>
);
}
}
export default Tasks;
Step 4: Create a new component for adding tasks
Create a new file TaskForm.js
in the src
directory and write the following code:
import React, { Component } from 'react';
import axios from 'axios';
class TaskForm extends Component {
constructor() {
super();
this.state = {
title: ''
};
}
handleChange = (e) => {
this.setState({
title: e.target.value
});
}
handleSubmit = (e) => {
e.preventDefault();
axios.post('/api/', { title: this.state.title })
.then(res => {
console.log(res);
this.setState({
title: ''
});
this.props.refreshTasks();
})
.catch(err => {
console.log(err);
});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text"
name="title"
value={this.state.title}
onChange={this.handleChange}
placeholder="Add task..." />
<button type="submit">Add</button>
</form>
);
}
}
export default TaskForm;
Step 5: Update App.js to use these components
In your App.js
, include the TaskForm
and Tasks
components:
import React, { Component } from 'react';
import Tasks from './Tasks';
import TaskForm from './TaskForm';
class App extends Component {
render() {
return (
<div className="App">
<TaskForm />
<Tasks />
</div>
);
}
}
export default App;
Finally, to connect your backend with frontend, use Django CORS headers in your Django application to handle the CORS headers, as both your frontend and backend are going to run on different servers.
That's it! Now you should be able to run both the Django server and the React development server and see your tasks being retrieved from the Django server and displayed in the React app.