[Django]-How to host Angular 6 application in Python Django?

2👍

Assumption: That django site is already running

Things needed to set up Angular 6 locally

  1. Install Node Js.

    https://nodejs.org/en/download/

  2. Install Angular cli Globally

    npm install -g @angular/cli

  3. Navigate to angular on the repo

    dir\angular

  4. Install the npm’s [libraries]

    npm install

  5. Serve the site

    npm serve [-o]

  6. Navigate to the hosted site

    http://localhost:4200/

Angular Libraries needed to support Django

npm install @angular-devkit/custom-webpack –save

npm install @angular-builders/custom-webpack –save

npm install webpack-bundle-tracker –save

Django Libraries needed to support Angular

pip install django-webpack-loader

File Architecture – I put my angular project within the djangodir off root

root > djangodir > angular

root > djangodir > static

root > djangodir > templates

root > djangodir > webpack-stats-angular.json

Set Up Angular for Django

1) Alter angular.json to include custom webpack config and change build type to builder

 "architect": {
    "build": {
      "builder": "@angular-builders/custom-webpack:browser",
      "options": {
        "customWebpackConfig": {
          "path": "./extra-webpack.config.js"
          },
        "outputPath": "../static/angular",

2) extra-webpack.config.js code

const BundleTracker = require('webpack-bundle-tracker');

module.exports = {
    plugins:[
        new BundleTracker({filename: '../webpack-stats-angular.json'})
    ],
    output: {
        path: require('path').resolve('../static/angular'),
        filename: "[name]-[hash].js"
    }
};

Set Up Django for Angular

1) settings.py – added webpack_loader to installed_apps

INSTALLED_APPS = [
    'webpack_loader'
]

2) settings.py – added webpack_loader

WEBPACK_LOADER = {    
    'DEFAULT': {
        'BUNDLE_DIR_NAME': 'angular/',
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats-angular.json'),
    }
}

3) requirements.txt – We have a script that pulls from a text file to include dependencies – to this we add

django-webpack-loader==0.6.0

4) urls.py – set up the init routing to the hello world angular app

from . import views as djangodir_views

urlpatterns = [
   # path('', include(router.urls)),
   path('', djangodir_views.serve_angular, name='serve_angular')
]

5) views.py – include url path

def serve_angular(request):
    return render(request, 'angular.html')

Angular.html Page:

{% load render_bundle from webpack_loader %}

<!doctype html>
<html lang="en">
<head>
    <base href="/">
    <title>Angular/TypeScript Hello World Project</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="Angular Hello World Starter">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
    <!-- <link href="assets/styles/styles.css" rel="stylesheet" /> -->
</head>
<body>
    <header class="navbar navbar-inner navbar-fixed-top">
        <nav class="container">
            <div class="navbar-header">
              <span class="app-title"></span>
            </div>
        </nav>
    </header>

    <main class="container">
        <app-root>
            Loading...
        </app-root>
        <br /><br />
    </main>

    <footer>
        <div class="navbar navbar-fixed-bottom">
            <div class="navbar-inner footer">
                <div class="container">
                    <footer>

                    </footer>
                </div>
            </div>
        </div>
    </footer>
{% render_bundle 'runtime' %}
{% render_bundle 'polyfills' %}
{% render_bundle 'styles' %}
{% render_bundle 'vendor' %}
{% render_bundle 'main' %}
</html>

References:

  1. Angular 6|5 Tutorial: Integrating Angular with Django
  2. Customizing Angular CLI 6 build — an alternative to ng eject
  3. Evolving your Django frontend
  4. Angular Hello World Example used

Routing:

In order for angular routing to work, you must

1) app-routing.module.ts – Add the routing to angular

const routes: Routes = [
  { path: '', component: TestComponent, data: { title: 'Home' }},
  { path: 'test', component: Test2Component, data: { title: 'Test' }}  
];

2) urls.py – Add the routing to Django – just point it to the same view

urlpatterns = [
    path('', djangodir_views.serve_angular, name='serve_angular'),
    path('test', djangodir_views.serve_angular, name='serve_angular')
]

3👍

Integrating Angular 8 and django 2.2

Used Visual Studio for Django 2.2 and Visual Studio Code for Angular 8

I tweaked the above solution and it ultimately worked. devised a simpler solution using some additional references (listed at the end) on top of the above solution.

Assuming:

  • angular is setup at: example/angular
  • django is setup at: example/django

Distribute angular files directly to django static folder

This is #1 key, the rest is glue (somewhat ugly) code to stitch the frameworks together as painless as possible.

At the console:

cd example/angular

ng build –prod –output-path ..\django\mysite\mysite\app\static\angular –output-hashing none –watch

Check Angular/CLI for command line switches and their use, the key here that the output of angular compilation goes directly to Django, no need for a middle man.

Maintain independent FE and BE for development and testing

Note: this is optional, you could "ruin" your angular development environment and put all django tags and attributes directly in angular, at the cost of losing FE – BE independence.

The index.html distributed in angular cannot be used "as is" in Django.

Here is such an example call it angular.html:

{% load static %}

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>mysite</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="{% static 'angular/favicon.ico' %}">
  <link rel="stylesheet" href="{% static 'angular/styles.css' %}">
</head>

<body>
  <app-root></app-root>
    <script src="{% static 'angular/runtime.js' %}"></script>
    <script src="{% static 'angular/polyfills-es5.js' %}"></script>
    <script src="{% static 'angular/polyfills.js' %}"></script>
    <script src="{% static 'angular/main.js' %}"></script>
</body>
</html>

Note: using only Django native language

Serve it in django like any other html

What else

Leave a comment