There are many alternatives to build a site , you need to select a client framework , a server platform, a database server and many other building blocks to help you link everything , develop, debug and deploy

One great option for server side development is python. With its huge number of packages and tools , python became a great programming language for desktop, server and web applications. Connecting to a database server? manipulating data? doing image and signal processing? writing a face recognition cloud based app? python will help you do these and much more in a very easy way with just few lines of code. For web development you can find many frameworks, the most popular is django

When you need to choose a client side framework its easier , first because we are using only one programming language – javascript and second because there are few options with clear differences. Most of the developers are using ReactJS or Angular. I prefer Angular

So i started to search how to create a site with Django on the server side and Angular 4 on client. I didn’t find a good working example, i had to make many changes but at the end i succeeded to create a site from scratch with:

Angular 4 on the client side

Django on the server side

All deployed to heroku

I will go over the steps and also post the result:

Install python 3

Install virtual environment:

# pip install virtualenv 1 # pip install virtualenv

create an empty folder

create and activate a virtual environmemt:

# virtualenv -p /usr/local/bin/python3 env # source env/bin/activate 1 2 3 # virtualenv -p /usr/local/bin/python3 env # source env/bin/activate

install Django

# pip install django 1 # pip install django

create the app

# django-admin startproject helloapp # python manage.py startapp first 1 2 3 # django-admin startproject helloapp # python manage.py startapp first

Add the module name (first) to the installed apps (setting.py):

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'first', ] 1 2 3 4 5 6 7 8 9 INSTALLED_APPS = [ 'django.contrib.admin' , 'django.contrib.auth' , 'django.contrib.contenttypes' , 'django.contrib.sessions' , 'django.contrib.messages' , 'django.contrib.staticfiles' , 'first' , ]

Add migration so you can change your database schema easily:

# python manage.py migrate 1 # python manage.py migrate

Run the server to see the first app:

# python manage.py runserver 1 # python manage.py runserver

You can now open your web browser and go to http://localhost:8000 to see its working.

Add some views to your app:

Add new entry to urls.py (urlpatterns):

url(r'^', include('first.urls')) 1 url ( r '^' , include ( 'first.urls' ) )

Add file urls.py to the App folder (first):

from django.conf.urls import url from first import views urlpatterns = [ url(r'^$', views.HomePageView.as_view()), url(r'^links/$' , views.LinksPageView.as_view()), ] 1 2 3 4 5 6 7 from django . conf . urls import url from first import views urlpatterns = [ url ( r '^$' , views . HomePageView . as_view ( ) ) , url ( r '^links/$' , views . LinksPageView . as_view ( ) ) , ]

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.shortcuts import render from django.views.generic import TemplateView # Create your views here. 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) 1 2 3 4 5 6 7 8 9 10 11 from django . shortcuts import render from django . views . generic import TemplateView # Create your views here. 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 )

Run the server again and see the results (try home page and /links address

Deploy the app to heroku

Create an heroku account

Create a Procfile on the root directory with this content :

web: gunicorn helloapp.wsgi --log-file – 1 web : gunicorn helloapp . wsgi -- log - file –

Install the following packages:

# pip install gunicorn # pip install dj-database-url # pip install whitenoise # pip install psycopg2 1 2 3 4 # pip install gunicorn # pip install dj-database-url # pip install whitenoise # pip install psycopg2

Add the following to the setting file (at the end):

# Update database configuration with $DATABASE_URL. import dj_database_url db_from_env = dj_database_url.config(conn_max_age=500) DATABASES['default'].update(db_from_env) # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.9/howto/static-files/ 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.django.GzipManifestStaticFilesStorage' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # Update database configuration with $DATABASE_URL. import dj_database_url db_from_env = dj_database_url . config ( conn_max_age = 500 ) DATABASES [ 'default' ] . update ( db_from_env ) # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.9/howto/static-files/ 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.django.GzipManifestStaticFilesStorage'

Add whitenoise to the middleware list of the settings file (the first line):

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', ] 1 2 3 4 5 6 7 8 9 10 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' , ]

Create a ‘static’ folder in helloapp folder

Save the installed packages:

# pip freeze > requirements.txt 1 # pip freeze > requirements.txt

login to heroku and create an application:

# heroku login # heroku create [appname] 1 2 # heroku login # heroku create [appname]

Add the appname to the ALLOWED_HOSTS in the settings file or put ‘*’ to allow any host:

ALLOWED_HOSTS = ['yourappname.herokuapp.com'] 1 ALLOWED_HOSTS = [ 'yourappname.herokuapp.com' ]

connect to your new app (or existing one):

# heroku git:remote -a [appname] 1 # heroku git:remote -a [appname]

init a git repository

# git init 1 # git init

Create a .gitignore file:

venv *.pyc staticfiles .env 1 2 3 4 venv * . pyc staticfiles . env

push the project to the remote storage:

# git add . # git commit -m "first" # git push heroku master 1 2 3 # git add . # git commit -m "first" # git push heroku master

Now go to the address appname.herokuapp.com and see the deployed website

To run heroku locally:

# heroku local web 1 # heroku local web

Configuring Angular 4 as client side

Install node.js

Install Angular cli

# npm install -g @angular/cli 1 # npm install -g @angular/cli

Create a new Angular project

# ng new testapp 1 # ng new testapp

Test it using local server:

# ng serve 1 # ng serve

Build the project

# ng build 1 # ng build

This will create dist folder with everything you need for deploying the client side

Integrating with Django project:

Copy the js files to the static folder on your Django project (helloapp/static)

Copy index.html generated by angular project to the templates folder – override the existing one (first/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 'inline.bundle.js' %}"></script> <script type="text/javascript" src="{% static 'polyfills.bundle.js' %}"></script> <script type="text/javascript" src="{% static 'styles.bundle.js' %}"></script> <script type="text/javascript" src="{% static 'vendor.bundle.js' %}"></script> <script type="text/javascript" src="{% static 'main.bundle.js' %}"></script></body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { % 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 'inline.bundle.js' %}" > </script> <script type = "text/javascript" src = "{% static 'polyfills.bundle.js' %}" > </script> <script type = "text/javascript" src = "{% static 'styles.bundle.js' %}" > </script> <script type = "text/javascript" src = "{% static 'vendor.bundle.js' %}" > </script> <script type = "text/javascript" src = "{% static 'main.bundle.js' %}" > </script> < / body > < / html >

note the use of static to tell Django to load the js files from the static folder (declared in settings.py)

Now you can generate and deploy

# git add . # git commit -m "first" # git push heroku master 1 2 3 # git add . # git commit -m "first" # git push heroku master

Example – http request from Angular to Django

Define another view in views.py file:

class Customers(TemplateView): def getCust(request): name='liran' return HttpResponse('{ "name":"' + name + '", "age":31, "city":"New York" }') 1 2 3 4 class Customers ( TemplateView ) : def getCust ( request ) : name = 'liran' return HttpResponse ( '{ "name":"' + name + '", "age":31, "city":"New York" }' )

Declare the new url in urls.py file

urlpatterns = [ url(r'^$', views.HomePageView.as_view()), url(r'^links/$' , views.LinksPageView.as_view()), url(r'^getcust/$',views.Customers.getCust), ] 1 2 3 4 5 urlpatterns = [ url ( r '^$' , views . HomePageView . as_view ( ) ) , url ( r '^links/$' , views . LinksPageView . as_view ( ) ) , url ( r '^getcust/$' , views . Customers . getCust ) , ]

Test it using the local web ( http://127.0.0.1:8000/getcust ) – you need to see the json response

Http request from Angular:

Add the HttpModule to the app.module.ts file:

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpModule } from '@angular/http'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpModule, ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { BrowserModule } from '@angular/platform-browser' ; import { NgModule } from '@angular/core' ; import { HttpModule } from '@angular/http' ; import { AppComponent } from './app.component' ; @ NgModule ( { declarations : [ AppComponent ] , imports : [ BrowserModule , HttpModule , ] , providers : [ ] , bootstrap : [ AppComponent ] } ) export class AppModule { }

On the button click event make the http request to the ‘getcust’ view

import { Component } from '@angular/core'; import {Http, Response} from '@angular/http'; import {Observable} from 'rxjs'; import 'rxjs/add/operator/map'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { constructor(private _http:Http) { this.c1.name = "eli" } title = 'app'; c1:Cust = new Cust(); click1(){ this.getAllBooks().subscribe(b => this.c1 = b) } getAllBooks() { return this._http .get("./getcust") .map(r => <Cust>r.json()) } } export class Cust{ name:string; age:number; city:string; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import { Component } from '@angular/core' ; import { Http , Response } from '@angular/http' ; import { Observable } from 'rxjs' ; import 'rxjs/add/operator/map' ; @ Component ( { selector : 'app-root' , templateUrl : './app.component.html' , styleUrls : [ './app.component.css' ] } ) export class AppComponent { constructor ( private _http: Http ) { this . c1 . name = "eli" } title = 'app' ; c1 : Cust = new Cust ( ) ; click1 ( ) { this . getAllBooks ( ) . subscribe ( b = > this . c1 = b ) } getAllBooks ( ) { return this . _http . get ( "./getcust" ) . map ( r = > < Cust > r . json ( ) ) } } export class Cust { name : string ; age : number ; city : string ; }

Add binding to the html file:

<div style="text-align:center"> <h1> Welcome to {{title}}! </h1> </div> <h2>Test App: {{c1.name}}</h2> <button (click)="click1()" >click me</button> 1 2 3 4 5 6 7 8 < div style = "text-align:center" > < h1 > Welcome to { { title } } ! < / h1 > < / div > < h2 > Test App : { { c1 . name } } < / h2 > < button ( click ) = "click1()" > click me < / button >

build the client side

# ng build 1 # ng build

Copy the js files to the static folder

Deploy the site again:

# git add . # git commit -m "first" # git push heroku master 1 2 3 # git add . # git commit -m "first" # git push heroku master

you can find the complete code both server and client here

Thats All !!!

Next post i’ll integrate NumPy, Matplotlib and Pandas

Subscribe to our list