18 months ago i posted the following post about integrating Angular and Django. Meanwhile, we have new releases and some updates.
Angular 7 is one of the best javascript frameworks. With typescript as a regular programming language , its separation of data and views, CSS and HTML, its finally feels like real programming on client side.
You can build the server side using many technologies: nodejs if you want to javascript also on the server, ASP.NET if you want microsoft on your back and many more
I prefer python. Its easy, dynamic , has tons of packages available and integrates with all kind of data – local, cloud, small and big
Python offers many frameworks to build a web application – I prefer Django
In this post, I will build a simple web application using:
I also use jetbrains tools : Webstorm for client side and pycharm for the server side, Using these tools, you can open an Angular cli project and django project and skip the basic setup steps
The server – Django and Django REST
I will go over the steps and also post the result:
- Install python 3
- create an empty folder
- create and activate a virtual environmemt:
# python -m venv venv # source venv/bin/activate
- install Django
# pip install django
- create the app
# django-admin startproject datatest # python manage.py startapp data
- Add migration so you can change your database schema easily:
# python manage.py migrate
- Run the server to see the first app:
# python manage.py runserver
You can now open your web browser and go to http://localhost:8000 to see its working.
- Install the following packages using pip
# pip install gunicorn # pip install dj-database-url # pip install whitenoise # pip install psycopg2-binary # pip install djangorestframework
Client Side – Angular 7
- Install node.js – LTS
- Install Angular cli
# npm install -g @angular/cli
- Create a new Angular project
# ng new testapp
- Test it using local server:
# ng serve
- Build the project
# ng build
This will create dist folder with everything you need for deploying the client side
Integrating with Django project:
- Copy the js files (including the map files) to the static folder on your Django project (data/static)
- Copy index.html generated by angular project to the templates folder – override the existing one (data/templates)
- Change the index.html file as follow:
{% load static %} <!doctype html> <html> <head> <meta charset="utf-8"> <title>Home</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <!-- index.html --> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <app-root>Loading...</app-root> <script type="text/javascript" src="{% static 'es2015-polyfills.js' %}"></script> <script type="text/javascript" src="{% static 'polyfills.js' %}"></script> <script type="text/javascript" src="{% static 'styles.js' %}"></script> <script type="text/javascript" src="{% static 'vendor.js' %}"></script> <script type="text/javascript" src="{% static 'runtime.js' %}"></script> <script type="text/javascript" src="{% static 'main.js' %}"></script></body> </html>
Update the settings.py file
On the django project we need to make some settings to enable the static folder and the REST framework
Add the rest framework to the installed apps:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'data.apps.DataConfig', 'rest_framework', ]
Update the middleware:
MIDDLEWARE = [ 'whitenoise.middleware.WhiteNoiseMiddleware', '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', ]
Set the static folder – add the following at the bottom of the settings file:
import dj_database_url db_from_env = dj_database_url.config(conn_max_age=500) DATABASES['default'].update(db_from_env) PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') STATIC_URL = '/static/' # Extra places for collectstatic to find static files. STATICFILES_DIRS = ( os.path.join(PROJECT_ROOT, 'static'), ) # Simplified static file serving. # https://warehouse.python.org/project/whitenoise/ STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Add some views and REST API – Server
- Add new entry to urls.py at the main project folder (datatest):
from django.conf.urls import url from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), url(r'^', include('data.urls')) ]
- Add file urls.py to the App folder (data). Set a router for customers REST API, add 2 simple views and one api entry
from django.conf.urls import url from django.urls import path, include from data import views from rest_framework import routers router = routers.DefaultRouter() router.register(r'customers', views.CustViewSet) urlpatterns = [ url(r'^$', views.HomePageView.as_view()), url(r'^links/$', views.LinksPageView.as_view()), # simple view url(r'^getcust/$',views.Customers.getCust), # simple view url(r'^apitest/$',views.CalcTest), # for REST API test ]
- Create a templates folder on the module folder(first) and add your html files (index.html, links.html)
- On the views.py file add the following class:
from django.http import HttpResponse, JsonResponse from django.shortcuts import render from django.views.generic import TemplateView # Create your views here. from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework.utils import json from rest_framework import serializers from rest_framework import viewsets from data.models import Customer class HomePageView(TemplateView): def get(self, request, **kwargs): return render(request, 'index.html', context=None) class LinksPageView(TemplateView): def get(self, request, **kwargs): return render(request, 'links.html', context=None) class Customers(TemplateView): def getCust(request): name='liran' return HttpResponse('{ "name":"' + name + '", "age":31, "city":"New York" }')
Django REST Framework
To use Django REST framework we add a simple function to multiply the given argument by 100. Add the following code to the views.py file:
@api_view(["POST"]) def CalcTest(x1): try: x=json.loads(x1.body) y=str(x*100) return JsonResponse("Result:"+y,safe=False) except ValueError as e: return Response(e.args[0],status.HTTP_400_BAD_REQUEST)
Now , the server side is ready, you can run the server and test the different views. You can’t test the REST API using the browser because it doesn’t support GET method (only POST)
Angular Client Code
To test the server functionality , we will build a simple view
To use http requests from angular, we need to add the HttpClient service class (instead of http module that is deprecated)
app.module.ts file
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpClientModule } from '@angular/common/http'; import { AppComponent } from './app.component'; import { BooksComponent } from './books/books.component'; @NgModule({ declarations: [ AppComponent, BooksComponent ], imports: [ BrowserModule, HttpClientModule, ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Now we can add some code to use the server views and API
app.component.ts
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'djint'; constructor(private _http:HttpClient) { this.c1.name = "eli" } c1:Cust = new Cust(); click1(){ this.getBooks().subscribe(b => this.c1.name = b.toString()) } click2(){ this.getAllBooks().subscribe(b => this.c1 = b) } getAllBooks() { return this._http .get<Cust>("./getcust") // GET request } getBooks() { return this._http .post("./apitest/","5") // POST request with argument } } export class Cust{ name:string; age:number; city:string; }
The first function create a get request and the second creates a post request. This is a simple example to build only the skeleton
app.component.html
<div style="text-align:center"> <h1> Welcome to {{ title }}! </h1> <h2>Test App: {{c1.name}}</h2> <button (click)="click1()" >click me</button> <button (click)="click2()" >click me</button> </div>
Now its all set. to test the code run build and copy the js files to the static folder:
# ng build # cp dist/djint/*.js ~/projects/datatest/data/static/ # cp dist/djint/*.js.map ~/projects/datatest/data/static/
Each time you change the client code, you need to repeat the build and copy process
To Download the complete code for both Angular and Django see this github repo
link: site
link: Click here
Want more?
- Integrate with NumPy, Matplotlib and Pandas
- Push notification using Web Sockets and Django Channels
14 thoughts on “Building a Web App with Angular, Django and Django REST”
Comments are closed.
Hi and thank you for this introduction to Angular, Django and Django REST. I’m a noob on Django/Django REST and convention escapes me (like folder structure). Could you post your final folder structure here so I can compare my interpretation of the instructions?
NVM. I found it on your GitHub:
https://github.com/dev-area/DjangoAngular7
Thanks!
nvm, I found it on your GitHub! Thanks again.
https://github.com/dev-area/DjangoAngular7
Nice but incomplete.
It is not working “out of the box”
Hi SHLOMO, were you able to create/find a build that was working “out of the box”?
If so, please share! Or explain how to get it to a working state 🙂
Thanks..works awesome…
Autolike, auto liker, auto like, Photo Liker, Autoliker, Auto Like, Auto Liker, Increase Likes, Status Liker, ZFN Liker, Working Auto Liker, Autoliker, autolike, Photo Auto Liker, autoliker, Status Auto Liker, Autolike International
django and angular for deployment purpose which process is best?
this
https://www.techiediaries.com/django-angular-tutorial/
or
https://devarea.com/building-a-web-app-with-angular-django-and-django-rest/
[…] https://devarea.com/building-a-web-app-with-angular-django-and-django-rest/#.XYz-JEZKhPZ […]
This article is very helpful! Thank you soooooooo much!!!!
Hi,
I have created a small django-angular application with separate django server and angular server frontend.
Now i have to build and deploy my application onto the server. I am going to follow devarea link to build and then deploy the application. Pls help me if i face some problems.
Hi, I have created a website using Angular, and I am trying to integrate Django into this Angular project.
In your example, you mentioned copying *.js and *.js.map from dist/djint folder, but in my project, there is no such folder. Inside dist folder, only server folder exists. So, even if I followed your example, I get 404 response because there is no main.js / runtime.js / etc. in static folder. So, where can I find those *.js and *.js.map files? What do I have to do to get all those files?
[…] Django and Angular app […]
Can Anyone help me with this
When I am reloading my page or hit any route other then / it gives me page not found error.
Actually I got to know when i am traversing through my application it uses our angular app router-outlet
but if i hit url directly it is giving me page not found error it is trying to find that route in django urls. Can anyone tell me how to manage this