Creating a Full Stack CRUD application with Django and Angular

Creating a Full Stack CRUD (Create, Read, Update, Delete) application with Django for the backend and Angular for the frontend involves multiple steps. Below is a step-by-step guide to help you build a complete application.


1. Set Up the Backend (Django)

1.1 Install Django

Start by setting up a virtual environment and installing Django.

# Install virtualenv
pip install virtualenv

# Create a virtual environment
virtualenv env

# Activate the virtual environment
source env/bin/activate   # For Linux/Mac
env\Scripts\activate      # For Windows

# Install Django and Django REST Framework
pip install django djangorestframework corsheaders

1.2 Start a Django Project

Create a new Django project and app.

# Start a Django project
django-admin startproject backend

cd backend

# Start an app
python manage.py startapp api

1.3 Configure Django Project

Add api, rest_framework, and corsheaders to your INSTALLED_APPS in backend/settings.py:

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

Add middleware for CORS (to allow Angular to communicate with the backend):

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    ...
]

CORS_ALLOW_ALL_ORIGINS = True  # Allow all domains (for development)

1.4 Create the Database Model

In api/models.py, define a simple model for a "Book" entity:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    price = models.DecimalField(max_digits=6, decimal_places=2)
    
    def __str__(self):
        return self.title

1.5 Create Migrations and Apply Them

Run the following commands to set up the database:

python manage.py makemigrations
python manage.py migrate

1.6 Create Serializers and Views

In api/serializers.py, create a serializer for the Book model:

from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

In api/views.py, add the views for CRUD operations:

from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

1.7 Add URL Routing for the API

In api/urls.py, define the URL patterns:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
router.register('books', BookViewSet, basename='book')

urlpatterns = [
    path('', include(router.urls)),
]

Include this in the main backend/urls.py:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')),
]

1.8 Run the Django Server

Start the Django server:

python manage.py runserver

Test the endpoints at:


2. Set Up the Frontend (Angular)


2.1 Install Angular CLI

Ensure Node.js and npm are installed. Install Angular CLI globally:

npm install -g @angular/cli

2.2 Create a New Angular Project

Generate a new Angular project:

ng new frontend
cd frontend

2.3 Generate a Book Service and Component

Use Angular CLI to create a service and component for books:

ng generate service services/book
ng generate component components/book

2.4 Install Angular HTTP Client

Ensure HttpClientModule is imported in app.module.ts:

import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [AppComponent, BookComponent],
  imports: [BrowserModule, HttpClientModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

2.5 Implement Book Service

Edit book.service.ts to interact with the Django backend:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

export interface Book {
  id?: number;
  title: string;
  author: string;
  published_date: string;
  price: number;
}

@Injectable({
  providedIn: 'root'
})
export class BookService {
  private apiUrl = 'http://127.0.0.1:8000/api/books/';

  constructor(private http: HttpClient) {}

  getBooks(): Observable<Book[]> {
    return this.http.get<Book[]>(this.apiUrl);
  }

  getBook(id: number): Observable<Book> {
    return this.http.get<Book>(`${this.apiUrl}${id}/`);
  }

  addBook(book: Book): Observable<Book> {
    return this.http.post<Book>(this.apiUrl, book);
  }

  updateBook(id: number, book: Book): Observable<Book> {
    return this.http.put<Book>(`${this.apiUrl}${id}/`, book);
  }

  deleteBook(id: number): Observable<void> {
    return this.http.delete<void>(`${this.apiUrl}${id}/`);
  }
}

2.6 Implement the Book Component

Edit book.component.ts to perform CRUD operations:

import { Component, OnInit } from '@angular/core';
import { BookService, Book } from 'src/app/services/book.service';

@Component({
  selector: 'app-book',
  templateUrl: './book.component.html',
  styleUrls: ['./book.component.css']
})
export class BookComponent implements OnInit {
  books: Book[] = [];
  newBook: Book = { title: '', author: '', published_date: '', price: 0 };

  constructor(private bookService: BookService) {}

  ngOnInit(): void {
    this.loadBooks();
  }

  loadBooks() {
    this.bookService.getBooks().subscribe((data) => (this.books = data));
  }

  addBook() {
    this.bookService.addBook(this.newBook).subscribe(() => {
      this.loadBooks();
      this.newBook = { title: '', author: '', published_date: '', price: 0 };
    });
  }

  deleteBook(id: number) {
    this.bookService.deleteBook(id).subscribe(() => this.loadBooks());
  }
}

2.7 Update the Book Component Template

Edit book.component.html:

<h2>Books</h2>
<form (submit)="addBook()">
  <input [(ngModel)]="newBook.title" placeholder="Title" required />
  <input [(ngModel)]="newBook.author" placeholder="Author" required />
  <input [(ngModel)]="newBook.published_date" placeholder="Published Date" required />
  <input [(ngModel)]="newBook.price" placeholder="Price" type="number" required />
  <button type="submit">Add Book</button>
</form>

<ul>
  <li *ngFor="let book of books">
    {{ book.title }} - {{ book.author }} - {{ book.published_date }} - ${{ book.price }}
    <button (click)="deleteBook(book.id!)">Delete</button>
  </li>
</ul>

2.8 Run the Angular App

Start the Angular development server:

ng serve

Visit http://localhost:4200 to interact with the frontend.


3. Testing and Final Touches

  • Ensure the backend and frontend are running simultaneously.
  • Test all CRUD operations.
  • For production, use ng build to build the Angular app and serve it using Django or a static file server.

With this guide, you now have a fully functioning Django + Angular CRUD app.

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete