Building front-end apps with Angular 9 using Python/Django CRUD REST API

Building front-end apps with Angular 9 using Python/Django CRUD REST API

This Angular 9 CRUD tutorial explains how to use Angular 9 to build front-end apps for their back-end REST APIs. Using Python & Django as the backend or use JSON-Server to mock the API if you don't want to deal with Python. Learn Angular 9 by example by building a full-stack CRUD — Create, Read, Update and Delete — web application

This tutorial is designed for developers that want to use Angular 9 to build front-end apps for their back-end REST APIs. You can either use Python & Django as the backend or use JSON-Server to mock the API if you don't want to deal with Python. We'll be showing both ways in this tutorial.

You will see by example how to build a CRUD REST API with Python.

The new features of Angular 9 include better performance and smaller bundles thanks to Ivy.

Throughout this tutorial, designed for beginners, you'll learn Angular by example by building a full-stack CRUD — Create, Read, Update and Delete — web application using the latest version of the most popular framework and platform for building mobile and desktop client side applications (also called SPAs or Single Page Applications), created and used internally by Google.

In the back-end we'll use Python with Django, the most popular pythonic web framework designed for perfectionists with deadlines.

In nutshell, you'll learn to generate apps, components and services and add routing.

You'll also learn to use various features such as HttpClient for sending AJAX requests and HTTP calls and subscribing to RxJS 6 Observables etc.

By the end of this tutorial, you'll learn by building a real world example application:

  • How to install the latest version of the CLI,
  • How to use the CLI to generate a new Angular 9 project,
  • How to build a simple CRM application,
  • What's a component and component-based architecture
  • How to use RxJS 6 Observables and operators (map() and filter() etc.)
  • How to create components,
  • How to add component routing and navigation,
  • How to use HttpClient to consume a REST API etc.
Prerequisites

You will need to have the following prerequisites in order to follow this tutorial:

  • A Python development environment. We use a Ubuntu system with Python 3.7 and pip installed but you can follow these instructions in a different system as long as you have Python 3 and pip installed. Also the commands shown here are bash commands which are available in Linux-based systems and macOS but if you use Windows CMD or Powershell , make sure to use the equivalent commands or install bash for Windows.
  • Node.js and npm installed on your system. They are required by Angular CLI.
  • Familiarity with TypeScript.

If you have these requirements, you are good to go!

Getting & Running the Python REST API Server

We'll be using a Python REST API that we have created in this tutorial. Go ahead and clone the project's code from GitHub using the following command:

$ git clone https://github.com/techiediaries/python-django-crm-rest-api.git 

Next, create and activate a virtual environment:

$ python3 -m venv .env
$ source .env/bin/activate

Next, navigate to your CRM project and install the requirements using pip:

$ cd python-django-crm-rest-api
$ pip install -r requirements.txt

Finally, you can run the development server using the following command:

$ python manage.py runserver

Your REST API will be available from the http://localhost:8000/ address with CORS enabled.

Mocking the Same REST API with json-server

If you don't want to use a real Python & Django REST API server, you can also use json-server to quickly mock the REST API.

First, let's install json-server in our system using the following command:

$ npm install -g json-server

Next, create a folder for your server and create a JSON file (data.json) with the following content:

{
    "users":[
        {
            "id": 1,
            "first_name": "Robert",
            "last_name": "Schwartz",
            "email": "[email protected]"
        }

    ],
    "accounts": [
        {
            "id": 1,
            "name": "",
            "email":"",
            "phone": "",
            "industry": "",
            "website": "",
            "description": "",
            "createdBy": 1,
            "createdAt": "",
            "isActive": true
        }
    ],
    "contacts": [
        {
            "id": 1,
            "first_name": "",
            "last_name": "",
            "account": 1,
            "status":1,
            "source": 1,
            "email": "",
            "phone": "",
            "address": "",
            "description": "",
            "createdBy": 1,
            "createdAt": "",
            "isActive": true
        }
    ],
    "activities": [
        {
            "id": 1,
            "description": "",
            "createdAt" : "",
            "contact": 1,
            "status": 1
        }
    ],
    "contactsources": [
        {
            "id":1,
            "source": ""
        }
    ],
    "contactstatuses": [
        {
            "id":1,
            "status": ""
        }
    ],
    "activitystatuses":[
        {
            "id":1,
            "status": ""
        }
    ]
}

We added empty entries for JSON data. Feel free to add your own data or use a tool like Faker.js to automatically generate fake data.

Next, you need to start the JSON server using:

$ json-server --watch data.json  

Your REST API server will be running at http://localhost:3000.

We'll have the following resources exposed:

  • http://localhost:3000/users
  • http://localhost:3000/accounts
  • http://localhost:3000/contacts
  • http://localhost:3000/activities
  • http://localhost:3000/contactsources
  • http://localhost:3000/contactstatuses
  • http://localhost:3000/activitystatuses

This is nearly the same REST API exposed by our real Python REST API server.

The example Angular application we'll be building is the front-end for the CRM RESTful API that will allow you to create accounts, contacts and activities. It's a perfect example for a CRUD (Create, Read, Update and Delete) application built as an SPA (Single Page Application). The example application is work on progress so we'll be building it through a series of tutorials and will be updated to contain advanced features such as RxJS and JWT authentication.

Installing the Angular CLI 9

Make sure you have Node.js installed, next run the following command in your terminal to install Angular CLI 9:

$ npm install @angular/[email protected] --global

At the time of this writing @angular/cli v9.0.0-rc will be installed.

Before the final release of Angular 9, you will need to use the @next tag to install the pre-release version.

You can check the installed version by running the following command:

$ ng version

Now, you're ready to create a project using Angular CLI 9. Simply run the following command in your terminal:

ng new ngsimplecrm

The CLI will automatically generate a bunch of files common to most Angular projects and install the required dependencies for your project.

The CLI will prompt you if Would you like to add Angular routing? (y/N), type y. And Which stylesheet format would you like to use? Choose CSS and type Enter.

Next, you can serve your application locally using the following commands:

$ cd ./ngsimplecrm
$ ng serve

The command will compile our project and finally will display the ** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ ** ℹ 「wdm」: Compiled successfully. message.

This means, your application is running at http://localhost:4200.

What's a Component?

A component is a TypeScript class with an HTML template and an optional set of CSS styles that control a part of the screen.

Components are the most important concept in Angular. An Angular application is basically a tree of components with a root component (the famous AppComponent). The root component is the one contained in the bootstrap array in the main NgModule module defined in the app.module.ts file.

One important aspect of components is re-usability. A component can be re-used throughout the application and even in other applications. Common and repeatable code that performs a certain task can be encapsulated into a re-usable component that can be called whenever we need the functionality it provides.

Each bootstrapped component is the base of its own tree of components. Inserting a bootstrapped component usually triggers a cascade of component creations that fill out that tree. source

What's a Component-Based Architecture?

An Angular application is made of several components forming a tree structure with parent and child components.

A component is an independent block of a big system (web application) that communicates with the other building blocks (components) of the system using inputs and outputs. A component has an associated view, data and behavior and may have parent and child components.

Components allow maximum re-usability, easy testing, maintenance and separation of concerns.

Let's now see this practically. Head over to your Angular project folder and open the src/app folder. You will find the following files:

  • app.component.css: the CSS file for the component
  • app.component.html: the HTML view for the component
  • app.component.spec.ts: the unit tests or spec file for the component
  • app.component.ts: the component code (data and behavior)
  • app.module.ts: the application main module

Except for the last file which contains the declaration of the application main (root) Module, all these files are used to create a component. It's the AppComponent: The root component of our application. All other components we are going to create next will be direct or un-direct children of the root component.

Demystifying the App Component

Go ahead and open the src/app/app.component.ts file and let's understand the code behind the root component of the application.

First, this is the code:

import { Component } from  '@angular/core';
@Component({
    selector:  'app-root',
    templateUrl:  './app.component.html',
    styleUrls: ['./app.component.css']
})
export  class  AppComponent {
    title  =  'app';
}

We first import the Component decorator from @angular/core then we use it to decorate the TypeScript class AppComponent. The Component decorator takes an object with many parameters such as:

  • selector: specifies the tag that can be used to call this component in HTML templates just like the standard HTML tags
  • templateUrl: indicates the path of the HTML template that will be used to display this component (you can also use the template parameter to include the template inline as a string)
  • styleUrls: specifies an array of URLs for CSS style-sheets for the component

The export keyword is used to export the component so that it can be imported from other components and modules in the application.

The title variable is a member variable that holds the string 'app'. There is nothing special about this variable and it's not a part of the canonical definition of an Angular component.

Now let's see the corresponding template for this component. If you open src/app/app.component.html this is what you'll find:

<div  style="text-align:center">
<h1>
Welcome to !
</h1>
    <img  width="300"  alt="Angular Logo"  src="data:image/svg+xml;....">
</div>

    <h2>Here are some links to help you start: </h2>
<ul>
    <li>
    <h2><a  target="_blank"  rel="noopener"  href="https://angular.io/tutorial">Tour of Heroes</a></h2>
    </li>
    <li>
    <h2><a  target="_blank"  rel="noopener"  href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
    </li>
    <li>
    <h2><a  target="_blank"  rel="noopener"  href="https://blog.angular.io/">Angular blog</a></h2>
    </li>
</ul>

The template is a normal HTML file (almost all HTML tags are valid to be used inside Angular templates except for some tags such as <script>, <html> and <body>) with the exception that it can contain template variables (in this case the title variable) or expressions (``) that can be used to insert values in the DOM dynamically. This is called interpolation or data binding. You can find more information about templates from the docs.

You can also use other components directly inside Angular templates (via the selector property) just like normal HTML.

Note: If you are familiar with the MVC (Model View Controller) pattern, the component class plays the role of the Controller and the HTML template plays the role of the View.

Components by Example

After getting the theory behind Angular components, let's now create the components for our simple CRM application.

Our REST API, built either with Django or JSON-Server, exposes these endpoints:

  • /accounts: create or read a paginated list of accounts

  • /accounts/<id>: read, update or delete an account

  • /contacts: create or read a paginated list of contacts

  • /contacts/<id>: read, update or delete a contact

  • /activities: create or read a paginated list of activities

  • /activities/<id>: read, update or delete an activity

  • /contactstatuses: create or read a paginated list of contact statuses

  • /activitystatuses: create or read a paginated list of activity statuses

  • /contactsources: create or read a paginated list of contact sources

Before adding routing to our application, we first need to create the application components - so based on the exposed REST API architecture we can initially divide our application into these components:

  • AccountListComponent: this component displays and controls a tabular list of accounts

  • AccountCreateComponent: this component displays and controls a form for creating or updating accounts

  • ContactListComponent: displays a table of contacts

  • ContactCreateComponent: displays a form to create or update a contact

  • ActivityListComponent: displays a table of activities

  • ActivityCreateComponent: displays a form to create or update an activity

Let's use the Angular CLI to create the components. Open a new terminal and run the following commands:

$ ng generate component AccountList
$ ng generate component AccountCreate

$ ng generate component ContactList
$ ng generate component ContactCreate

$ ng generate component ActivityList
$ ng generate component ActivityCreate

This is the output of the first command:

CREATE src/app/account-list/account-list.component.css (0 bytes)
CREATE src/app/account-list/account-list.component.html (31 bytes)
CREATE src/app/account-list/account-list.component.spec.ts (664 bytes)
CREATE src/app/account-list/account-list.component.ts (292 bytes)
UPDATE src/app/app.module.ts (418 bytes)

You can see that the command generates all the files to define a component and also updates src/app/app.module.ts to include the component.

If you open src/app/app.module.ts after running all commands, you can see that all components are automatically added to the AppModule declarations array:

import { BrowserModule } from  '@angular/platform-browser';
import { NgModule } from  '@angular/core';

import { AppComponent } from  './app.component';
import { AccountListComponent } from  './account-list/account-list.component';
import { AccountCreateComponent } from  './account-create/account-create.component';
import { ContactListComponent } from  './contact-list/contact-list.component';
import { ContactCreateComponent } from  './contact-create/contact-create.component';

@NgModule({

declarations: [
    AppComponent,
    AccountListComponent,
    AccountCreateComponent,
    ContactListComponent,
    ContactCreateComponent,
    ActivityListComponent,
    ActivityCreateComponent 
],
imports: [
    BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export  class  AppModule { }

Note: If you are creating components manually, you need to make sure to include them manually so they can be recognized as part of the module.

Setting up HttpClient

Now that we've created the various components, let's set up HttpClient in our Angular 9 project to consume the RESTful API back-end.

You simply need to add HttpClientModule to the imports array of the main application module:

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

@NgModule({

declarations: [
// [...]
],

imports: [

// [...]

HttpClientModule
],
providers: [],
bootstrap: [AppComponent]

})

export  class  AppModule { }

We can now use HttpClient in our application.

Create Services

A service is a global class that can be injected in any component. It's used to encapsulate code that can be common between multiple components in one place instead of repeating it throughout various components.

Now, let's create the services that encapsulates all the code needed for interacting with the REST API. Using Angular CLI 8 run the following commands:

$ ng generate service services/contact
$ ng generate service services/activity
$ ng generate service services/account

Note: Since we have multiple services, we can put them in a services folder or whatever you want to call it.

Injecting HttpClient in the Services

Open the src/app/services/contact.service.ts file then import and inject HttpClient:

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

@Injectable({
providedIn:  'root'
})

export  class  ContactService {

    constructor(private  httpClient:  HttpClient) {}

}

Note: You will need to do the same for the other services.

Angular provides a way to register services/providers directly in the @Injectable() decorator by using the new providedIn attribute. This attribute accepts any module of your application or 'root' for the main app module. Now you don't have to include your service in the providers array of your module.

Conclusion

Throughout this tutorial for beginners, we've seen, by building a simple real world CRUD example, how to use different Angular 9 concepts to create simple full-stack CRUD application.

Python Django Tutorial | Django Course

Python Django Tutorial | Django Course

🔥Intellipaat Django course: https://intellipaat.com/python-django-training/ 👉This Python Django tutorial will help you learn what is django web development &...

This Python Django tutorial will help you learn what is django web development & application, what is django and introduction to django framework, how to install django and start programming, how to create a django project and how to build django app. There is a short django project as well to master this python django framework.

Why should you watch this Django tutorial?

You can learn Django much faster than any other programming language and this Django tutorial helps you do just that. Our Django tutorial has been created with extensive inputs from the industry so that you can learn Django and apply it for real world scenarios.

How to Build a Chat application with Django, Python and React

How to Build a Chat application with Django, Python and React

In this post, we will use Stream, an API for chat that takes care of WebSocket connections and other heavy lifting using Go, Raft and RocksDB. Let's go Building a Chat application with Django, Python and React

Unlike other tutorials, I’m not using Python/Django for WebSocket connections. While doing so may seem cool from a tech perspective, it’s pretty sluggish and expensive — especially if you have a halfway decent number of users. Languages such as C++, Go and Elixir are much better at handling the core of chat.

In this tutorial, we will use Stream, an API for chat that takes care of WebSocket connections and other heavy lifting using Go, Raft and RocksDB.

The GitHub repo for the code below can be found at https://github.com/GetStream/python-chat-example.

Before we start thinking about the Python chat side of things let’s spin up a simple React frontend, so we have something nice and visual to look at:

$ yarn global add create-react-app
$ brew install node && brew install yarn # skip if installed
$ create-react-app chat-frontend
$ cd chat-frontend
$ yarn add stream-chat-react

Replace the code in src/App.js with:

import React from "react";
import {
  Chat,
  Channel,
  ChannelHeader,
  Thread,
  Window
} from "stream-chat-react";
import { MessageList, MessageInput } from "stream-chat-react";
import { StreamChat } from "stream-chat";

import "stream-chat-react/dist/css/index.css";

const chatClient = new StreamChat("qk4nn7rpcn75"); // Demo Stream Key
const userToken =
  "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiY29vbC1za3ktOSJ9.mhikC6HPqPKoCP4aHHfuH9dFgPQ2Fth5QoRAfolJjC4"; // Demo Stream Token

chatClient.setUser(
  {
    id: "cool-sky-9",
    name: "Cool sky",
    image: "https://getstream.io/random_svg/?id=cool-sky-9&name=Cool+sky"
  },
  userToken
);

const channel = chatClient.channel("messaging", "godevs", {
  // image and name are required, however, you can add custom fields
  image:
    "https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png",
  name: "Talk about Go"
});

const App = () => (
  <Chat client={chatClient} theme={"messaging light"}>
    <Channel channel={channel}>
      <Window>
        <ChannelHeader />
        <MessageList />
        <MessageInput />
      </Window>
      <Thread />
    </Channel>
  </Chat>
);

export default App;

Next, run yarn start to see the chat in action!

Make sure you have Python 3.7 up and running.

$ brew install python3

$ pip install virtualenv virtualenvwrapper
$ export WORKON_HOME=~/Envs
$ source /usr/local/bin/virtualenvwrapper.sh
$ mkvirtualenv chatexample -p `which python3`
$ workon chatexample

If that does not work, please try this snippet:

$ python3 -m venv chatexample
$ source chatexample/bin/activate

Now that you’re in your virtual env you should see python 3 when you run:

$ python --version

To kick off a new Django project, use the following snippet:

$ pip install django
$ django-admin startproject mychat

And to start your app:

$ cd mychat
$ python manage.py runserver

Now, when you open http://localhost:8000, you should see this:

As a next step lets setup Django’s user auth.

$ python manage.py migrate
$ python manage.py createsuperuser
$ python manage.py runserver

Visit http://localhost:8000/admin/ and log in. Voila!

You should see the Django admin screen as shown below:

One of my favorite packages for integrating react with Django is Django Rest Framework. To make everything work, we will need to create endpoints for:

We could build those ourselves; however, there is a package called Djoser that has already solved this problem. It configured the necessary API endpoints for user registration, login, password reset, etc.

To install Djoser, use the following snippet:

$ pip install djangorestframework djoser

Then, edit urls.py and change the file to contain:

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('auth/', include('djoser.urls')),
    path('auth/', include('djoser.urls.authtoken')),
]

Once complete, edit settings.py and make the following changes:

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

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    )
}

For more on the API endpoints that Djoser exposes

Now, let’s go ahead and test the registration endpoint:

$ curl -X POST http://127.0.0.1:8000/auth/users/ --data 'username=djoser&password=alpine12'

Now we need to customize the Djoser views to generate tokens for Stream. Let’s get started.

Let’s organize our files a bit and create a chat app folder in our project (make sure that you are in the correct directory):

$ python manage.py startapp auth

Install stream-chat:

$ pip install stream-chat

Create a custom serializer in auth/serializers.py with the following logic:

from djoser.serializers import TokenSerializer
from rest_framework import serializers
from djoser.conf import settings as djoser_settings
from stream_chat import StreamChat
from django.conf import settings

class StreamTokenSerializer(TokenSerializer):
    stream_token = serializers.SerializerMethodField()

    class Meta:
        model = djoser_settings.TOKEN_MODEL
        fields = ('auth_token','stream_token')

    def get_stream_token(self, obj):
        client = StreamChat(api_key=settings.STREAM_API_KEY, api_secret=settings.STREAM_API_SECRET)
        token = client.create_token(obj.user.id)

        return token

And last, use the custom serializer by updating your settings.py file:

STREAM_API_KEY = YOUR_STREAM_API_KEY # https://getstream.io/dashboard/
STREAM_API_SECRET = YOUR_STREAM_API_SECRET
DJOSER = {
    'SERIALIZERS': {
        'token': 'auth.serializers.StreamTokenSerializer',
    }
}

Rerun your migration:

$ python manage.py migrate

To verify that it works, hit the login endpoint with a POST request:

$ curl -X POST http://127.0.0.1:8000/auth/token/login/ --data 'username=djoser&password=alpine12'

Both the auth_token and stream_token should be returned.

Adding an auth later to the frontend is an essential step for obvious reasons. In our case, it’s especially useful because we can fetch a user token from the backend API (powered by Python) and dynamically use it when sending messages.

First, install the CORS middleware package for Django:

$ pip install django-cors-headers

Then, modify your settings.py to reference the djors-cors-header middleware:

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

And finally, add the following to your settings.py file:

CORS_ORIGIN_ALLOW_ALL = True

The next step requires a few modifications to be made to your frontend. To start, you will want to ensure that you have all of the dependencies installed via yarn:

$ yarn add axios react-dom react-router-dom

Next, create the following files within your src/ directory:

  • AuthedRoute.js
  • UnauthedRoute.js
  • withSession.js
  • Login.js
  • Chat.js

App.js

import React from "react";
import { BrowserRouter as Router, Switch } from "react-router-dom";

import Chat from "./Chat";
import Login from "./Login";

import UnauthedRoute from "./UnauthedRoute";
import AuthedRoute from "./AuthedRoute";

const App = () => (
  <Router>
    <Switch>
      <UnauthedRoute path="/auth/login" component={Login} />
      <AuthedRoute path="/" component={Chat} />
    </Switch>
  </Router>
);

export default App;

AuthedRoute.js

import React from "react";
import { Redirect, Route } from "react-router-dom";

const AuthedRoute = ({ component: Component, loading, ...rest }) => {
  const isAuthed = Boolean(localStorage.getItem("token"));
  return (
    <Route
      {...rest}
      render={props =>
        loading ? (
          <p>Loading...</p>
        ) : isAuthed ? (
          <Component history={props.history} {...rest} />
        ) : (
          <Redirect
            to={{
              pathname: "/auth/login",
              state: { next: props.location }
            }}
          />
        )
      }
    />
  );
};

export default AuthedRoute;

UnauthedRoute.js

import React from "react";
import { Redirect, Route } from "react-router-dom";

const AuthedRoute = ({ component: Component, loading, ...rest }) => {
  const isAuthed = Boolean(localStorage.getItem("token"));
  return (
    <Route
      {...rest}
      render={props =>
        loading ? (
          <p>Loading...</p>
        ) : !isAuthed ? (
          <Component history={props.history} {...rest} />
        ) : (
          <Redirect
            to={{
              pathname: "/"
            }}
          />
        )
      }
    />
  );
};

export default AuthedRoute;

withSession.js

import React from "react";
import { withRouter } from "react-router";

export default (Component, unAuthed = false) => {
  const WithSession = ({ user = {}, streamToken, ...props }) =>
    user.id || unAuthed ? (
      <Component
        userId={user.id}
        user={user}
        session={window.streamSession}
        {...props}
      />
    ) : (
      <Component {...props} />
    );

  return withRouter(WithSession);
};

Login.js

import React, { Component } from "react";
import axios from "axios";

class Login extends Component {
  constructor(props) {
    super(props);

    this.state = {
      loading: false,
      email: "",
      password: ""
    };

    this.initStream = this.initStream.bind(this);
  }

  async initStream() {
    await this.setState({
      loading: true
    });

    const base = "http://localhost:8000";

    const formData = new FormData();
    formData.set("username", this.state.email);
    formData.set("password", this.state.password);

    const registration = await axios({
      method: "POST",
      url: `${base}/auth/users/`,
      data: formData,
      config: {
        headers: { "Content-Type": "multipart/form-data" }
      }
    });

    const authorization = await axios({
      method: "POST",
      url: `${base}/auth/token/login/`,
      data: formData,
      config: {
        headers: { "Content-Type": "multipart/form-data" }
      }
    });

    localStorage.setItem("token", authorization.data.stream_token);

    await this.setState({
      loading: false
    });

    this.props.history.push("/");
  }

  handleChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

  render() {
    return (
      <div className="login-root">
        <div className="login-card">
          <h4>Login</h4>
          <input
            type="text"
            placeholder="Email"
            name="email"
            onChange={e => this.handleChange(e)}
          />
          <input
            type="password"
            placeholder="Password"
            name="password"
            onChange={e => this.handleChange(e)}
          />
          <button onClick={this.initStream}>Submit</button>
        </div>
      </div>
    );
  }
}

export default Login;

Chat.js

import React, { Component } from "react";
import {
  Chat,
  Channel,
  ChannelHeader,
  Thread,
  Window
} from "stream-chat-react";
import { MessageList, MessageInput } from "stream-chat-react";
import { StreamChat } from "stream-chat";

import "stream-chat-react/dist/css/index.css";

class App extends Component {
  constructor(props) {
    super(props);
    this.client = new StreamChat("<YOUR_STREAM_APP_ID>");

    this.client.setUser(
      {
        id: "cool-sky-9",
        name: "Cool Sky",
        image: "https://getstream.io/random_svg/?id=cool-sky-9&name=Cool+sky"
      },
      localStorage.getItem("token")
    );

    this.channel = this.client.channel("messaging", "godevs", {
      image:
        "https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png",
      name: "Talk about Go"
    });
  }

  render() {
    return (
      <Chat client={this.client} theme={"messaging light"}>
        <Channel channel={this.channel}>
          <Window>
            <ChannelHeader />
            <MessageList />
            <MessageInput />
          </Window>
          <Thread />
        </Channel>
      </Chat>
    );
  }
}

export default App;

Be sure to replace YOUR_STREAM_APP_ID with a valid Stream App ID which can be found on the dashboard.

Restart your frontend application and you should be hit with an auth wall! Enter your email and password and a token will be requested and stored in local storage.

Occasionally, you will want to write to the chat API using your backend Python-based server. Here’s a quick management command that you can use:

Verify that installed apps looks like this in settings.py:

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

Next, create the directory chat/management/commands. In that directory, add a file called broadcast.py with this content:

from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from stream_chat import StreamChat

class Command(BaseCommand):
    help = 'Broadcast the message on your channel'

    def add_arguments(self, parser):
        parser.add_argument('--message')

    def handle(self, *args, **options):
        client = StreamChat(api_key=settings.STREAM_API_KEY, api_secret=settings.STREAM_API_SECRET)
        client.update_user({"id": "system", "name": "The Server"})
        channel = client.channel("messaging", "kung-fu")
        channel.create("system")
        response = channel.send_message({"text": "AMA about kung-fu"}, 'system')
        self.stdout.write(self.style.SUCCESS('Successfully posted a message with id "%s"' % response['message']['id']))

You can try posting a message to the chat like this:

$ python manage.py broadcast --message hello

And you should see a response like this:

I hope you enjoyed this tutorial on building a chat application with Django, Python and React!

Thank for reading !