Multi Tier Web App with Python Django and PostgreSQL

Prerequisites

  • An AWS account with an Ubuntu instance, Django 5.1.5, Python 3.12.3, PostgreSQL 16.6 installed, and basic knowledge of Python and Django are required.

    What is Python?

    Python is a high-level, interpreted programming language known for its simplicity and readability, widely used in web development, data science, AI, machine learning, and automation, with a clean syntax that is ideal for both beginners and experienced developers, and it is the primary language for writing Django applications, making understanding Python essential for building web applications with Django.

    What is Django?

    Django is a high-level, open-source web framework that uses Python to quickly and securely build robust and maintainable web applications, following the Model-View-Template (MVT) pattern to separate application logic, user interface, and data.

    What is PostgreSQL?

    PostgreSQL is a powerful, open-source object-relational database management system known for its reliability, scalability, and performance, making it popular for web development and data-driven applications.

    Python Django Business applications

    1. E-commerce and Retail, 2. Content Management Systems, 3. Hotel booking and reservation systems, 4. Event management and ticketing systems, 5. Customer Relationship Management (CRM) systems.

      Install Python3 and set up a Virtual Environment on Ubuntu

      Update your system and install pip (Python Package Installer).

    sudo apt update
    sudo apt install python3-pip

Create and activate a Python virtual environment in Ubuntu.

    sudo apt install python3-venv
    python3 -m venv myenv
    source myenv/bin/activate

Install Django on Ubuntu by first updating your system, installing pip, and setting up a Python virtual environment.

With the virtual environment activated, run the command to install Django.

    pip install django

Install the pre-built binary package by downloading and setting it up on your system.

  • Install psycopg2-binary, a pre-built package for PostgreSQL database interaction in Python, which simplifies and speeds up the installation process by avoiding source compilation.
    pip install psycopg2-binary

Set up a new Django application on Ubuntu.

  • Run this command to start a new Django project.
    django-admin startproject myproject
    cd myproject

Install and Configure PostgreSQL on Ubuntu

Install PostgreSQL on Ubuntu.

sudo apt install postgresql

After installing PostgreSQL, verify that the PostgreSQL service is running.

sudo systemctl status postgresql

Log in to the PostgreSQL database using the psql command as the default postgres user to access the interactive shell.

sudo -u postgres psql

After running the command, you'll be logged into the PostgreSQL shell where you can execute SQL commands.

Use the following command to create a database.

CREATE DATABASE mydatabase;

To create a user named 'myuser' with the password 'mypassword'.

CREATE USER myuser WITH PASSWORD 'mypassword';

To grant privileges to the user named 'myuser'.

This SQL command in PostgreSQL grants full access to the database (mydatabase) for the user (myuser).

GRANT ALL PRIVILEGES ON DATABASE mydatabase TO myuser;

Connect to the database named mydatabase.

\c mydatabase

The command \c mydatabase in PostgreSQL connects to the database named mydatabase, and you can grant superuser privileges to the user myuser.

 ALTER USER myuser WITH SUPERUSER;

Exit PostgreSQL.

\q

Configure Database Settings for Django App

Open settings.py and modify the DATABASES section.

nano myproject/settings.py

Change the DATABASES dictionary to use PostgreSQL.

  • Replace the default SQLite database setting with the following configuration.
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',                                     
        'USER': 'myuser',                                            
        'PASSWORD': 'mypassword',                      
        'HOST': ' <EC2-Public-IP>',
        'PORT': '5432',
    }
}

  • Find the ALLOWED_HOSTS setting and change it accordingly.
ALLOWED_HOSTS = ['<EC2-Public-IP>', 'localhost', '127.0.0.1']

Create a Django Application for user Signup

  • To keep your project organized, create a new Django app called accounts to manage user-related features like signup.
python manage.py startapp accounts

Add 'accounts' to INSTALLED_APPS in myproject/settings.py.

nano myproject/settings.py
INSTALLED_APPS = [
    ...
    'accounts',
]

Develop the Signup Page in Django

  • Navigate to the accounts directory and check if the forms.py file exists; if not, create the forms.py file..
cd accounts
touch forms.py
nano forms.py

Add the following code to the forms.py file.

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

class SignupForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']
  • The SignupForm class inherits from UserCreationForm to manage user registration, adding a required email field and specifying the model as User with fields username, email, password1, and password2.

    Create the Signup page View

    • In this step, we will create a view in Django to manage the signup process, including form submission, validation, and user creation.Open views.py inside accounts.
    vi views.py
    from django.shortcuts import render
    from .forms import SignupForm
    from django.contrib import messages

    def signup(request):
        if request.method == 'POST':
            form = SignupForm(request.POST)
            if form.is_valid():
                form.save()
                messages.success(request, "Account created successfully!")
                return render(request, 'accounts/signup.html', {'form': form})  
        else:
            form = SignupForm()
        return render(request, 'accounts/signup.html', {'form': form})
  • The signup view manages user registration by processing POST requests to validate and create a new user, displaying a success message upon creation, and handling GET requests to render an empty form for user input when the page is first loaded.Save and exit.

Set Up URLs for Signup page

  • In this step, we will set up the URL path for the signup page to connect it to the previously created view, enabling users to access the signup page through a specific URL, and create the urls.py file in the accounts app.
    touch urls.py
    nano urls.py
  • Add the following code to the urls.py file.
    from django.urls import path
    from . import views

    urlpatterns = [
        path('signup/', views.signup, name='signup'),
    ]
  • This code sets up the URL pattern for the signup page in the accounts app, using 'signup/' as the path, views.signup as the view function, name='signup' for easy reference, allowing users to access the signup page at /accounts/signup/, and instructs to save, exit, and include accounts.urls in myproject/urls.py.
    cd ..
    nano myproject/urls.py

Change it as shown below.

  •   from django.contrib import admin
      from django.urls import path, include
    
      urlpatterns = [
          path('admin/', admin.site.urls),
          path('accounts/', include('accounts.urls')),
      ]
    
    • Save and exit.

Create Signup Template

Create the HTML template for the signup page, defining how the form will display fields for username, email, and password to the user.

    mkdir -p accounts/templates

    mkdir -p accounts/templates/accounts

    ls accounts/templates

    touch accounts/templates/accounts/signup.html

    ls accounts/templates/accounts/
  • Open signup.html and insert the following HTML code.
    nano accounts/templates/accounts/signup.html
  • Insert the following code into signup.html.
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Sign Up</title>
    </head>
    <body>
        <h2>Sign Up</h2>
        <form method="post">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit">Sign Up</button>
        </form>
    </body>
    </html>
  • The template generates a signup form that securely submits user input using POST, includes a CSRF token for protection, displays form fields as paragraphs, and features a submit button.

Verify PostgreSQL Configuration

  • To connect to a remote PostgreSQL server, make sure it is configured to accept remote connections by editing the postgresql.conf file.
    sudo nano /etc/postgresql/16/main/postgresql.conf

Ensure the line listen_addresses is set to '*'.

listen_addresses = '*'

  • Edit the postgresql.conf file to allow PostgreSQL to listen for connections from any IP address, and modify the pg_hba.conf file to permit connections from your local machine.
sudo vi /etc/postgresql/16/main/pg_hba.conf
  • Add a line to permit connections from any IP address or a specific IP range if necessary.
host    all    all    0.0.0.0/0    md5
  • Allow any IP to connect using password authentication by setting 0.0.0.0/0, restrict further by specifying an IP range, and restart PostgreSQL to apply changes.
sudo systemctl restart postgresql

Allow port 5432 through firewall/security group

  • Ensure the firewall on the remote server allows PostgreSQL's default port (5432) by running the appropriate command.
sudo ufw allow 5432/tcp
  • If your instance is in the cloud, allow the port in the cloud security group.

Test the Connection with Postgresql

Test if your Django project can connect to the PostgreSQL database successfully.

psql -h ip_addr -U myuser -d mydatabase

Apply Database Migrations

  • In Django, migrations update the database schema to match changes in your application's models, such as adding fields or creating new models.
python manage.py makemigrations
python manage.py migrate
  • It applies changes made in your models to the actual database.

Create a Superuser in Django

  • In this step, we will create a superuser account that gives you administrator privileges to access the Django admin interface. The superuser can manage users, view and edit data, and perform other administrative tasks.
python manage.py createsuperuser

Run the Django Server in Ubuntu 24.04 LTS

python manage.py runserver 0.0.0.0:8000
  • 0.0.0.0: This allows the server to be accessed from any IP address on your machine, and 8000 is the default port Django uses, so you can access the Django admin panel by opening your browser.
http://public_ip_addr:8000/admin/

  • Log in with the superuser credentials you created, open your browser to public_ip_addr:8000/accounts/signup, and after successful registration, you can view user information in the PostgreSQL database.
sudo -u postgres psql
\c mydatabase
\du
select * from auth_user;

We will set up a Django signup page integrated with PostgreSQL, enabling users to register accounts, store them in a PostgreSQL database, and access the Django admin interface.