Django Chat App (Without Django Channels)
Tags: django, python, tailwindcss
Published: 2022-10-02 17:52:04

Ever wondered what a Django chat application would be like without looking like it's based on discord or slack? Look no further! This article is about that thought being brought to life.

![](https://cdn-images-1.medium.com/max/3196/1*MRxB2HJ_rnNkAD220IPaVA.png)

I'm assuming that you already have some knowledge in python and python Django. you might need a bit of tailwind knowledge if you want to modify the templates.

## Creating your Project

create a folder called **chat_django **and navigate to the folder.

    mkdir chat_django && cd chat_django

For this Project, I will use a virtual environment.

    # first
    python3 -m venv env
    # second
    source env/bin/activate # macos/linux
    env/scripts/activate.bat # windows

Next, install Django and [cripsy_tailwind](https://github.com/django-crispy-forms/crispy-tailwind). Crispy_tailwind is the tailwind version of bootstrap's cripsy_form used to style forms templates.

    # install django
    pip install Django
    # install crispy tailwind
    pip install crispy-tailwind

Now, we create our Django project.

    django-admin startproject django_chat && cd django_chat

Finally, create an app called **chat.**

    python3 manage.py startapp chat

## Setting up your Project

We are going to make the following changes to our Project **settings.py**

At the top of **settings.py** add import os.

![importing os to avoid PostSix error and get the theme path](https://cdn-images-1.medium.com/max/2000/1*Z4UJCVUfF-zNrxptxyZbEw.png)

To our **INSTALLED_APPS = [] **we'll add our custom app(chat), crispy forms, and crispy_tailwind.

![](https://cdn-images-1.medium.com/max/2000/1*WE9RUCoXkcRICZLvE3n2aA.png)

We will be storing our static files/folders and templates in a folder called **theme **in our Django project directory.

    mkdir theme

Your project folder should be something like this.

    chat_django
    |_env
    |_django_chat
      |_chat
      |_django_chat
      |_theme

Go to your theme directory and create these three directories: **src**, **templates**, and **static**

    cd theme && mkdir src templates static

We are going to make those folders accessible to Django since they are not in Django's default specified location.

in your **settings.py **add

    (BASE_DIR / 'themes/templates')

to the **TEMPLATES = [] **like so:

![](https://cdn-images-1.medium.com/max/2988/1*iiWoPuYceHReoC0NIGKYTA.png)

In your **settings.py **add a **STATICFILES_DIRS = []**, this will tell Django which directory to read the static files from.

![](https://cdn-images-1.medium.com/max/2616/1*HxCuwzaOJeBTLfZEAvM7Mg.png)

we should be done with the **settings.py** for now.

## Chat app setup

### Models

In the **models.py **of our chat app, we are going to create a User model and a Message model.

 1. User Model: For our user model, we will be extending the **AbstractUser **from the **django.contrib.auth.models**. we are using the AbstractUser to get the auth benefits of the Django default User model. Our User model will have two fields. A username field, and an email field. Both will be unique.

![](https://cdn-images-1.medium.com/max/2620/1*Ba-9KNtt0vwZHi7EpIEYIg.png)

2. Message Model: We'll use Django's default database model for the message model. We'll add a field for the sender and recipient which will be a reference to the **UserProfile **model. We'll also add a date field, to get the DateTime of the messages, and a is_read field to mark read messages

![](https://cdn-images-1.medium.com/max/3936/1*SOQ8xqOi3wF5vetPGhVdSg.png)

Below the **Message** Model Meta class, we are going to add two functions:

 1. **get_all_messages(id_1, id_2): **the function takes your primary key and the primary key of the person whose chat inbox you're opening and gets all the messages between you two and sorts them by date.

![](https://cdn-images-1.medium.com/max/5148/1*PcHXmdrxp32_dSuDHOi91Q.png)

2. **get_message_list(u): **takes your primary key, filters all messages that have either your primary key as the recipient or the sender, sorts them by username and date, and returns them while removing all other messages that do not have your primary key.

![](https://cdn-images-1.medium.com/max/4976/1*9xWh2OrNrUX0JvCroDlqxA.png)

### Form

Create a forms.py file in your **chat** app. Since we want users to signup for the app, we are going to create a custom signup form using **UserCreationForm **from the **django.contrib.auth.forms. **Because we are using crispy forms, the only fields we'll need to call in our Signup form will be the username and the email; the rest will be taken care of by the **UserCreationForm. **The form will add password fields and create a user with no admin or staff privileges.

![](https://cdn-images-1.medium.com/max/3324/1*AFTgctQnJQh_5fxcOpu0KQ.png)

## Views

For the **views.py, **we will be creating four views :

 1. **signup view**: sign up users

 2. **messages list view**: display all messages per user for the user logged in

 3. **inbox view**: a chat view between you and the other user

 4. **users list view**: to find new users to chat with

Before we continue with creating the views, at the top of the views file, you need to import the following:

![](https://cdn-images-1.medium.com/max/2748/1*XHGM52qP9wRpThYfcPqvyA.png)

Now for the views:
>  Signup View

![A signup view that logs the user in after they signup](https://cdn-images-1.medium.com/max/4708/1*8AxmBsjNFpRH5oCcc5SgwQ.png)
>  Messages list view

![The view has a LoginRequiredMixin, so authenticated users can only access it. Uses the get_message_list function from the message model](https://cdn-images-1.medium.com/max/3968/1*ceQ09UXmH2y8XVrkCJTg_Q.png)
>  Inbox view

![We are using a username in the url instead of the primary key. The above code gets the username for the view and also passes the user name to the post function](https://cdn-images-1.medium.com/max/3700/1*EJjOK2hv9EmjMyT1umr6Hg.png)

![Uses the get_all_messages and get_message_list to display messages in the chat and the messages list for the template](https://cdn-images-1.medium.com/max/5752/1*HcByJ6M-ytGHQZmNvuIxPg.png)

![This function is called on to send a message in the chat.](https://cdn-images-1.medium.com/max/4672/1*uBpTQMMmQWncJrq6LEdyLg.png)
>  UserListsView

![Display all users, excluding the user logged in](https://cdn-images-1.medium.com/max/3936/1*aLPOTOzd3lGEL8KOR2Xd9w.png)

### Urls

By default, Django apps are not created with a urls.py file, so you'll need to create it as you did with the forms.py. We are not going to build custom logout and login views, so we'll use Django's default **LoginView** and **LogoutView** views from the **django.contrib.auth.views**. All we'll need to do is to render a template or a url redirect (for LogoutView) for the default auth views.

In the urls.py add the following:

![](https://cdn-images-1.medium.com/max/3868/1*QsGYnPIDl7RabsxcrU83wA.png)

## Settings again?

For our final tweak in settings.py we are going to add**AUTH_USER_MODEL **to specify which model we want to authenticate as the user model, we will also set the urls for the login and logout views and the redirect urls.

Add the following code under the STATICFILES_DIRS

![](https://cdn-images-1.medium.com/max/2000/1*Pj-iKuW8-4H03DR4-NRafw.png)

## Theme/Templates/static

To set up the tailwind, static, and templates, check out this article:
[**Django + Tailwind Simplified**](https://medium.com/@gr1nch3/django-tailwind-simplified-8befa0a281d4)

### crispy_tailwind

To use crispy tailwind with our crispy forms, we need to add the following to the settings.py

![](https://cdn-images-1.medium.com/max/2008/1*0aW_Tu4O0J_huarx7TAXcA.png)

When done, the results should be:

![](https://cdn-images-1.medium.com/max/3200/1*WlCmGSMDbJbe4ydQfeZJsQ.png)

Project git: [https://github.com/gr1nch3/django_chat.git](https://github.com/gr1nch3/django_chat.git)

Thanks for reading!

## Extras

To continue the Project, you could add:

 1. unread messages count

 2. a group chat feature

 3. maybe a better template than I did

 4. images or files upload within the chat