In this tutorial, we will learn how to build a full stack Django + Angular + MongoDB example with a CRUD App. The back-end server uses Python 3/Django with Rest Framework for REST APIs. Front-end side is made with Angular 15/14/13/12/11/10/8, HTTPClient & Router.
Contents
- Django + Angular + MongoDB example Overview
- Django + Angular + MongoDB Architecture
- Django Rest Apis Back-end
- Overview
- Technology
- Project structure
- Install Django REST framework
- Setup new Django project
- Connect Django project to MongoDB database
- Setup new Django app for Rest CRUD Api
- Configure CORS and middleware
- Define the Django Model
- Migrate Data Model to MongoDB database
- Create Serializer class for Data Model
- Define Routes to Views functions
- Write API Views
- Run the Django Rest Api Server
- Angular Front-end
- Further Reading
- Conclusion
Django + Angular + MongoDB example Overview
We will build a full-stack Django + Angular Tutorial Application working with MongoDB in that:
- Each Tutorial has id, title, description, published status.
- We can create, retrieve, update, delete Tutorials.
- We can also find Tutorials by title.
The images below shows screenshots of our System.
– Create a Tutorial:
– Retrieve all items:
– Click on Edit button to view an item details:
On this Page, you can:
- change status to Published using Publish button
- remove the Tutorial from Database using Delete button
- update the Tutorial details on Database with Update button
– Search items by title:
– Here is our MongoDB collection:
Django + Angular + MongoDB Architecture
This is the application architecture we’re gonna build:
– Django exports REST Apis using Django Rest Framework & interacts with MongoDB Database using Django Model.
– Angular Client sends HTTP Requests and retrieve HTTP Responses using HttpClient Module, shows data on the components. We also use Angular Router for navigating to pages.
Django Rest Apis Back-end
Overview
The following diagram shows the architecture of our Django CRUD Rest Apis App with MongoDB database:
- HTTP requests will be matched by Url Patterns and passed to the Views
- Views processes the HTTP requests and returns HTTP responses (with the help of Serializer)
- Serializer serializes/deserializes data model objects
- Models contains essential fields and behaviors for CRUD Operations with MongoDB Database
These are APIs that Django App will export:
Methods | Urls | Actions |
---|---|---|
POST | /api/tutorials | create new Tutorial |
GET | /api/tutorials | retrieve all Tutorials |
GET | /api/tutorials/:id | retrieve a Tutorial by :id |
PUT | /api/tutorials/:id | update a Tutorial by :id |
DELETE | /api/tutorials/:id | delete a Tutorial by :id |
DELETE | /api/tutorials | delete all Tutorials |
GET | /api/tutorials?title=[keyword] | find all Tutorials which title contains keyword |
Technology
- Python 3.7
- Django 2.1.15
- Django Rest Framework 3.11.0
- djongo 1.3.1
- django-cors-headers 3.2.1
- MongoDB 3.4 or higher
Project structure
This is our Django project structure:
Let me explain it briefly.
- tutorials/apps.py: declares
TutorialsConfig
class (subclass ofdjango.apps.AppConfig
) that represents Rest CRUD Apis app and its configuration. - DjangoRestApiMongoDB/settings.py: contains settings for our Django project: MongoDB Database engine,
INSTALLED_APPS
list with Django REST framework, Tutorials Application, CORS andMIDDLEWARE
. - tutorials/models.py: defines Tutorial data model class (subclass of
django.db.models.Model
). - migrations/0001_initial.py: is created when we make migrations for the data model, and will be used for generating MongoDB database collection.
- tutorials/serializers.py: manages serialization and deserialization with
TutorialSerializer
class (subclass ofrest_framework.serializers.ModelSerializer
). - tutorials/views.py: contains functions to process HTTP requests and produce HTTP responses (using
TutorialSerializer
). - tutorials/urls.py: defines URL patterns along with request functions in the Views.
- DjangoRestApiMongoDB/urls.py: also has URL patterns that includes
tutorials.urls
, it is the root URL configurations.
Install Django REST framework
Django REST framework helps us to build RESTful Web Services flexibly.
To install this package, run command:
pip install djangorestframework
Setup new Django project
Let’s create a new Django project with command:
django-admin startproject DjangoRestApiMongoDB
You can see the following folder tree when the process is done.
Now open settings.py and add Django REST framework to the INSTALLED_APPS
array here.
INSTALLED_APPS = [
...
# Django REST framework
'rest_framework',
]
Connect Django project to MongoDB database
We need a Django MongoDb connector to work with MongoDb database.
In this tutorial, we’re gonna use djongo.
Run the command: pip install djongo
.
Then we need to setup MongoDb Database engine.
So open settings.py and change declaration of DATABASES
:
DATABASES = {
'default': {
'ENGINE': 'djongo',
'NAME': 'bezkoder_db',
'HOST': '127.0.0.1',
'PORT': 27017,
}
}
Setup new Django app for Rest CRUD Api
Run following commands to create new Django app tutorials:
cd DjangoRestApiMongoDB
python manage.py startapp tutorials
The project directory now looks like:
Open tutorials/apps.py, you can see TutorialsConfig
class (subclass of django.apps.AppConfig
). This is the Django app and its configuration that we’ve just created.
from django.apps import AppConfig
class TutorialsConfig(AppConfig):
name = 'tutorials'
Don’t forget to add this app to INSTALLED_APPS
array in settings.py:
INSTALLED_APPS = [
...
# Tutorials application
'tutorials.apps.TutorialsConfig',
]
Configure CORS and middleware
We need to allow requests to our Django application from other origins.
In this example, we’re gonna configure CORS to accept requests from localhost:8081
.
First, install the django-cors-headers library:
pip install django-cors-headers
In settings.py, add configuration for CORS:
INSTALLED_APPS = [
...
# CORS
'corsheaders',
]
You also need to add a middleware class to listen in on responses:
MIDDLEWARE = [
...
# CORS
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
]
Note: CorsMiddleware
should be placed as high as possible, especially before any middleware that can generate responses such as CommonMiddleware
.
Next, set CORS_ORIGIN_ALLOW_ALL and add the host to CORS_ORIGIN_WHITELIST:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
'http://localhost:8081',
)
- CORS_ORIGIN_ALLOW_ALL: If
True
, all origins will be accepted (not use the whitelist below). Defaults toFalse
. - CORS_ORIGIN_WHITELIST: List of origins that are authorized to make cross-site HTTP requests. Defaults to
[]
.
Define the Django Model
Open tutorials/models.py, add Tutorial
class as subclass of django.db.models.Model
.
There are 3 fields: title, description, published.
from django.db import models
class Tutorial(models.Model):
title = models.CharField(max_length=70, blank=False, default='')
description = models.CharField(max_length=200,blank=False, default='')
published = models.BooleanField(default=False)
Each field is specified as a class attribute, and each attribute maps to a database column.
id field is added automatically.
Migrate Data Model to MongoDB database
Run the Python script: python manage.py makemigrations tutorials
.
The console will show:
Migrations for 'tutorials':
tutorials\migrations\0001_initial.py
- Create model Tutorial
New file 0001_initial.py has just been generated in tutorials/migrations folder. It includes code to create Tutorial
data model:
# Generated by Django 2.1.15
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Tutorial',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(default='', max_length=70)),
('description', models.CharField(default='', max_length=200)),
('published', models.BooleanField(default=False)),
],
),
]
The generated code defines Migration
class (subclass of the django.db.migrations.Migration
).
It has operations array that contains operation for creating collection for Customer model: migrations.CreateModel()
.
The call to this will create a new model in the project history and a corresponding collection in the MongoDB database to match it.
Now run the following Python script to apply the generated migration above:
python manage.py migrate tutorials
The console will show:
Operations to perform:
Apply all migrations: tutorials
Running migrations:
Applying tutorials.0001_initial... OK
Check MongoDB database, you can see that a collection for Tutorial
model was generated automatically with the name: tutorials_tutorial:
Create Serializer class for Data Model
Let’s create TutorialSerializer
class that will manage serialization and deserialization from JSON.
It inherit from rest_framework.serializers.ModelSerializer
superclass which automatically populates a set of fields
and default validators
. We need to specify the model class here.
tutorials/serializers.py
from rest_framework import serializers
from tutorials.models import Tutorial
class TutorialSerializer(serializers.ModelSerializer):
class Meta:
model = Tutorial
fields = ('id',
'title',
'description',
'published')
In the inner class Meta
, we declare 2 attributes:
model
: the model for Serializerfields
: a tuple of field names to be included in the serialization
Define Routes to Views functions
Let determine how the server will response for HTTP request (GET, POST, PUT, DELETE) with some endpoints. We’re gonna define the routes:
/api/tutorials
: GET, POST, DELETE/api/tutorials/:id
: GET, PUT, DELETE/api/tutorials/published
: GET
Inside tutorials app, create urls.py file with urlpatterns
containing url
s to be matched with the functions in the views.py:
from django.conf.urls import url
from tutorials import views
urlpatterns = [
url(r'^api/tutorials$', views.tutorial_list),
url(r'^api/tutorials/(?P<pk>[0-9]+)$', views.tutorial_detail),
url(r'^api/tutorials/published$', views.tutorial_list_published)
]
Don’t forget to include this URL patterns in root URL configurations.
Open DjangoRestApiMongoDB/urls.py and modify the content with the following code:
from django.conf.urls import url, include
urlpatterns = [
url(r'^', include('tutorials.urls')),
]
Write API Views
Now we create the functions that are pointed in Url Patterns above:
– tutorial_list()
: GET list of tutorials, POST a new tutorial, DELETE all tutorials
– tutorial_detail()
: GET / PUT / DELETE tutorial by ‘id’
– tutorial_list_published()
: GET all published tutorials
These functions process HTTP requests and make CRUD Operations to database via Django Model.
Open tutorials/views.py and write following code:
from django.shortcuts import render
...
@api_view(['GET', 'POST', 'DELETE'])
def tutorial_list(request):
# GET list of tutorials, POST a new tutorial, DELETE all tutorials
@api_view(['GET', 'PUT', 'DELETE'])
def tutorial_detail(request, pk):
# find tutorial by pk (id)
try:
tutorial = Tutorial.objects.get(pk=pk)
except Tutorial.DoesNotExist:
return JsonResponse({'message': 'The tutorial does not exist'}, status=status.HTTP_404_NOT_FOUND)
# GET / PUT / DELETE tutorial
@api_view(['GET'])
def tutorial_list_published(request):
# GET all published tutorials
You can continue with step by step (with Github) to implement this Django Server in the post:
MongoDB + Django Rest Framework CRUD Rest API example
Run the Django Rest Api Server
Run our Django Project with command: python manage.py runserver 8080
.
The console shows:
Performing system checks...
System check identified no issues (0 silenced).
Django version 2.1.15, using settings 'DjangoRestApiMongoDB.settings'
Starting development server at http://127.0.0.1:8080/
Quit the server with CTRL-BREAK.
Angular Front-end
Overview
– The App
component is a container with router-outlet
. It has navbar that links to routes paths via routerLink
.
– TutorialsList
component gets and displays Tutorials.
– Tutorial
component has form for editing Tutorial’s details based on :id
.
– AddTutorial
component has form for submission new Tutorial.
– These Components call TutorialService
methods which use Angular HTTPClient
to make HTTP requests and receive responses.
Project Structure
– tutorial.model.ts
exports the main class model: Tutorial
.
– There are 3 components: tutorials-list
, tutorial-details
, add-tutorial
.
– tutorial.service
has methods for sending HTTP requests to the Apis.
– app-routing.module.ts defines routes for each component.
– app
component contains router view and navigation bar.
– app.module.ts
declares Angular components and import necessary modules.
Set up App Module
Open app.module.ts and import FormsModule
, HttpClientModule
:
...
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [ ... ],
imports: [
...
FormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Define Routes for Angular AppRoutingModule
There are 3 main routes:
– /tutorials
for tutorials-list
component
– /tutorials/:id
for tutorial-details
component
– /add
for add-tutorial
component
app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { TutorialsListComponent } from './components/tutorials-list/tutorials-list.component';
import { TutorialDetailsComponent } from './components/tutorial-details/tutorial-details.component';
import { AddTutorialComponent } from './components/add-tutorial/add-tutorial.component';
const routes: Routes = [
{ path: '', redirectTo: 'tutorials', pathMatch: 'full' },
{ path: 'tutorials', component: TutorialsListComponent },
{ path: 'tutorials/:id', component: TutorialDetailsComponent },
{ path: 'add', component: AddTutorialComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Create Data Service
This service will use Angular HTTPClient
to send HTTP requests.
You can see that its functions includes CRUD operations and finder method.
services/tutorial.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Tutorial } from '../models/tutorial.model';
const baseUrl = 'http://localhost:8080/api/tutorials';
@Injectable({
providedIn: 'root'
})
export class TutorialService {
constructor(private http: HttpClient) { }
getAll(): Observable<Tutorial[]> {
return this.http.get<Tutorial[]>(baseUrl);
}
get(id: any): Observable<Tutorial> {
return this.http.get(`${baseUrl}/${id}`);
}
create(data: any): Observable<any> {
return this.http.post(baseUrl, data);
}
update(id: any, data: any): Observable<any> {
return this.http.put(`${baseUrl}/${id}`, data);
}
delete(id: any): Observable<any> {
return this.http.delete(`${baseUrl}/${id}`);
}
deleteAll(): Observable<any> {
return this.http.delete(baseUrl);
}
findByTitle(title: any): Observable<Tutorial[]> {
return this.http.get<Tutorial[]>(`${baseUrl}?title=${title}`);
}
}
Create Angular Components
As you’ve known before, there are 3 components corresponding to 3 routes defined in AppRoutingModule
.
- Add new Item Component
- List of items Component
- Item details Component
You can continue with step by step to implement this Angular App (with Github) in one of following posts:
– Angular 8 CRUD example with Web API
– Angular 10 CRUD example with Web API
– Angular 11 CRUD example with Web API
– Angular 12 CRUD example with Web API
– Angular 13 CRUD example with Web API
– Angular 14 CRUD example with Web API
– Angular 15 CRUD example with Web API
Run the Angular App
You can run this App with command: ng serve --port 8081
.
If the process is successful, open Browser with Url: http://localhost:8081/
and check it.
Further Reading
- Django Rest Framework quich start
- Django Model
- https://github.com/nesdis/djongo
- Angular HttpClient
- Angular Template Syntax
Other back-end servers that work well with the Angular Client:
Conclusion
Now we have an overview of Django + Angular + MongoDB example when building a CRUD App that interacts with database. We also take a look at client-server architecture for REST API using Django Rest Framework (Python 3), as well as Angular project structure for building a front-end app to make HTTP requests and consume responses.
Next tutorials show you more details about how to implement the system (including Github source code):
– Back-end
– Front-end:
- Using Angular 8
- Using Angular 10
- Using Angular 11
- Using Angular 12
- Using Angular 13
- Using Angular 14
- Using Angular 15