14 KiB
Of course. Let's build this from the ground up. This guide will be a step-by-step tutorial on how to start the project, assuming you have zero lines of code.
We will use the recommended stack: Django (Backend), React (Frontend), and PostgreSQL (Database), with Vite for the React project setup as it's faster and more modern.
Phase 0: Prerequisites (Your Developer Machine Setup)
Before you write any code, make sure you have these tools installed on your computer:
- Git: For version control. Download Git
- Python: (Version 3.8+). Download Python
- Node.js and npm: (Node LTS version). This is for managing the React project. Download Node.js
- PostgreSQL: The database itself. You need to install and run the PostgreSQL server. Download PostgreSQL
- A Code Editor: Visual Studio Code (VS Code) is highly recommended. It's free and has excellent extensions for Python/Django and React.
- An API Client (Optional but recommended): Tools like Postman or Insomnia are invaluable for testing your backend API endpoints without needing a frontend.
Phase 1: Project Initialization & Structure
Let's create the overall project structure. Open your terminal or command prompt.
# 1. Create a main project folder
mkdir incident-reporter-app
cd incident-reporter-app
# 2. Initialize a Git repository to track all your changes
git init
# 3. Create folders to separate the backend and frontend
mkdir backend
mkdir frontend
Your folder structure should look like this:
incident-reporter-app/
├── .git/
├── backend/ <-- Your Django project will live here
└── frontend/ <-- Your React project will live here
Phase 2: Building the Backend Foundation (Django)
We'll start with the backend to create the data structure and API that the frontend will eventually use.
-
Navigate into the backend folder and create a Python virtual environment. A virtual environment keeps your project's Python packages separate from others on your system. It's a critical best practice.
cd backend python -m venv venv # "venv" is the name of the environment folder -
Activate the virtual environment.
- On Windows:
venv\Scripts\activate - On macOS/Linux:
source venv/bin/activate - (Your terminal prompt should now show
(venv)at the beginning.)
- On Windows:
-
Install core Django packages.
pip install django djangorestframework psycopg2-binary django-cors-headersdjango: The main framework.djangorestframework: A toolkit for building web APIs. A huge time-saver.psycopg2-binary: The adapter to let Django talk to your PostgreSQL database.django-cors-headers: This will be crucial later to allow your React app (on a different port) to talk to your Django API.
-
Create the Django Project and App. In Django, a "project" is the main container, and "apps" are components that do specific things (like handling incidents).
# Create the project. The "." means create it in the current directory. django-admin startproject config . # Create our first app for handling incidents python manage.py startapp incidents -
Configure the Database in
config/settings.py.- First, open PostgreSQL and create a new database for your project. Let's call it
incident_db. - Now, find the
DATABASESsection in yourconfig/settings.pyfile and change it to use PostgreSQL:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'incident_db', # The name you chose for your DB 'USER': 'your_postgres_user', # Your PostgreSQL username 'PASSWORD': 'your_password', # Your PostgreSQL password 'HOST': 'localhost', # Or '127.0.0.1' 'PORT': '5432', } } - First, open PostgreSQL and create a new database for your project. Let's call it
-
Add your new apps to
INSTALLED_APPSinconfig/settings.py. Django needs to know about them.INSTALLED_APPS = [ # ... other apps 'rest_framework', # Add this 'corsheaders', # Add this 'incidents', # Add this (your app) ] -
Define your Data Models in
incidents/models.py. This is where you define your database schema using Python code.from django.db import models from django.contrib.auth.models import User class Incident(models.Model): STATUS_CHOICES = ( ('open', 'Open'), ('in_progress', 'In Progress'), ('closed', 'Closed'), ) employee_name = models.CharField(max_length=200) incident_date = models.DateTimeField() location = models.CharField(max_length=255) description = models.TextField() status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='open') created_at = models.DateTimeField(auto_now_add=True) # Link to the user who reported it reported_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self): return f"Incident at {self.location} on {self.incident_date.strftime('%Y-%m-%d')}" -
Create and run database migrations. This process tells Django to look at your models and create the actual SQL tables in your PostgreSQL database.
python manage.py makemigrations python manage.py migrate -
Create a superuser so you can log into Django's built-in admin panel.
python manage.py createsuperuserFollow the prompts to create a username and password.
-
Test the Admin Panel.
- Start the development server:
python manage.py runserver - Go to
http://127.0.0.1:8000/adminin your browser. - Log in with the superuser credentials. You can see Users, but not Incidents yet.
- Last step: Register your model so it shows up. In
incidents/admin.py, add:from django.contrib import admin from .models import Incident admin.site.register(Incident) - Now refresh the admin page. You can now create, view, update, and delete incidents directly from this powerful, pre-built interface! This is a huge Django win.
- Start the development server:
You have now successfully set up the entire backend foundation!
Phase 3: Building the API Endpoints (Django REST Framework)
Now we need to create API endpoints so our future React app can communicate with the backend.
-
Create a
serializers.pyfile inside yourincidentsfolder. A serializer converts your complex Django model data into simple JSON that can be sent over the web.incidents/serializers.py:
from rest_framework import serializers from .models import Incident class IncidentSerializer(serializers.ModelSerializer): class Meta: model = Incident fields = '__all__' # Include all fields from the model -
Create the API Views in
incidents/views.py. A view handles incoming requests (like GET for fetching data or POST for creating data).ModelViewSetfrom DRF is magical—it creates all the necessary endpoints for you (list, create, retrieve, update, delete).incidents/views.py:
from rest_framework import viewsets from .models import Incident from .serializers import IncidentSerializer class IncidentViewSet(viewsets.ModelViewSet): queryset = Incident.objects.all().order_by('-created_at') serializer_class = IncidentSerializer -
Wire up the URLs. We need to tell Django what URL should point to our new API view.
-
First, in your project's
config/urls.py:from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('incidents.urls')), # Point /api/ to our app's urls ] -
Then, create a new
urls.pyfile inside yourincidentsapp folder.incidents/urls.py:
from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import IncidentViewSet # Create a router and register our viewsets with it. router = DefaultRouter() router.register(r'incidents', IncidentViewSet, basename='incident') # The API URLs are now determined automatically by the router. urlpatterns = [ path('', include(router.urls)), ]
-
Backend Checkpoint!
- Run the server again:
python manage.py runserver - Go to
http://127.0.0.1:8000/api/incidents/in your browser. - You should see the Django REST Framework's Browsable API. You can now view existing incidents and even
POSTto create new ones directly from your browser. You have a working API.
Phase 4: Building the Frontend (React)
Now let's switch to the frontend.
-
Open a NEW terminal. Do not close your Django server terminal. Navigate to the
frontenddirectory.# (In a new terminal) cd incident-reporter-app/frontend -
Create a new React project using Vite. Vite is a modern build tool that is significantly faster than the older
create-react-app.npm create vite@latest- It will ask for a project name. Enter
.to use the current directory. - Select React as the framework.
- Select JavaScript or TypeScript (JavaScript is fine to start).
- It will ask for a project name. Enter
-
Install dependencies and run the app.
npm install npm install axios react-router-dom @mui/material @emotion/react @emotion/styled # Install key libraries npm run devaxios: For making API calls to your Django backend.react-router-dom: For managing navigation and pages in your app.@mui/material: A fantastic UI component library to make your app look professional quickly.
Your React app is now running, typically at
http://localhost:5173.
Phase 5: Connecting Frontend to Backend
Now, let's make React talk to Django. You will hit a CORS error. This is a security feature browsers enforce. Here's how to fix it.
-
Configure
django-cors-headersin your backendconfig/settings.py:# Add this to the MIDDLEWARE list, high up but after SessionMiddleware MIDDLEWARE = [ # ... 'corsheaders.middleware.CorsMiddleware', # Add this 'django.middleware.common.CommonMiddleware', # ... ] # Add this at the bottom of the file CORS_ALLOWED_ORIGINS = [ "http://localhost:5173", # The address of your React app "http://127.0.0.1:5173", ] -
Restart your Django server for the changes to take effect.
-
Fetch data in your React app. Replace the code in
frontend/src/App.jsxwith a basic example to fetch and display incidents.frontend/src/App.jsx:
import { useState, useEffect } from 'react'; import axios from 'axios'; function App() { const [incidents, setIncidents] = useState([]); const [error, setError] = useState(null); useEffect(() => { // Fetch incidents from the Django API axios.get('http://127.0.0.1:8000/api/incidents/') .then(response => { setIncidents(response.data); }) .catch(error => { console.error("There was an error fetching the data!", error); setError("Could not load data. Is the backend server running?"); }); }, []); // The empty array means this effect runs once when the component mounts if (error) { return <div>Error: {error}</div>; } return ( <div> <h1>Incident Reports</h1> <ul> {incidents.length > 0 ? ( incidents.map(incident => ( <li key={incident.id}> <strong>{incident.location}:</strong> {incident.description} ({incident.status}) </li> )) ) : ( <p>No incidents reported yet.</p> )} </ul> </div> ); } export default App;
GRAND FINALE: Go to your React app in the browser (http://localhost:5173). You should see the list of incidents that you created in the Django admin panel.
You now have a full-stack web application, with a working connection between a React frontend and a Django/PostgreSQL backend.
Next Steps from Here:
- Build Out the Forms: Use React libraries like
React Hook Formand UI components from MUI to build the incident creation form. - Implement POST Requests: Make the form's "Submit" button send a
POSTrequest withaxiosto/api/incidents/to create new records. - Add User Authentication: Implement login/logout on the frontend that talks to Django's auth endpoints.
- Implement RBAC: In your Django views, check
request.user.roleto restrict what data users can see or what actions they can perform. - Build Features: Start implementing PDF generation, the signature pad, and file uploads to S3, one by one.
- Containerize with Docker: Once your app is more mature, "Dockerize" it to prepare for deployment.
- Deploy: Choose a HIPAA-compliant host and deploy your application.