Django is a free and open-source high-level Python Web framework. Being a Python Web framework, Django requires Python.
In this guide, we will demonstrate how to install and configure Django. We will then set up Nginx and Apache to sit in front of our Django application.

We will also be using the mod_wsgi Apache module that can communicate with Django over the WSGI interface specification.

1. Install the latest version of python and Django
Please refer to /install-django for a guide on how to install python and Django.

2. Install mod_wsgi

a) Download latest version of mod_wsgi. As of writing, the latest version was 4.6.5

# cd /usr/local/src
# wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.6.5.zip

b) Unzip and build mod-wsgi with the version of python installed in step 1 above

# cd /usr/local/src
# unzip 4.6.5.zip
# cd mod_wsgi-4.6.5
# ./configure ./configure --with-apxs=/usr/local/apache/bin/apxs --with-python=/usr/local/bin/python3.7
# make
# make install

c) Add mod_wsgi module to httpd.conf file

echo "LoadModule wsgi_module modules/mod_wsgi.so" >> /usr/local/apache/conf/httpd.conf

d) Restart Apache

systemctl restart httpd

e)Check if mod_wsgi is loaded

/usr/local/apache/bin/httpd -M | grep wsgi

3. Setup and Configure Django

a) Create account to host Django App

With Django installed in step 1, we will create an account on CWP to host our Django application.
CWP.Admin Left Menu -> User accounts -> New Account -> fill the details and click create
Now we Create a Django project called myproj using django-admin tool in your Docroot.

# cd /home/username/public_html/
# django-admin startproject myproj .

The above commands will create a file - manage.py and a folder called myproj inside /home/username/public_html

b) Alter project settings
The first thing we should do with our newly created project files is to alter the settings.

# cd /home/username/public_html/myproj
# nano settings.py

i) Locate ALLOWED_HOSTS.Inside the square brackets, enter your server's public IP address, domain name or both. Each value should be wrapped in quotes and separated by a comma like a normal Python list:

ALLOWED_HOSTS = ["server_domain_or_IP"]
eg : ALLOWED_HOSTS = ["8.8.8.8"]

ii) At the bottom of the file, we will add a line to configure this directory. Django uses the STATIC_ROOT setting to determine static files directory, where Django will place static files so that the webserver can serve these easily.Put the following under the STATIC_URL = '/static/'

STATIC_ROOT = '/home/username/public_html/static'

Note: Please make sure the static directory is created in the location specified above.

iii) Setup MySQL Database.
CWP.user left menu –> SQL services –> MySQL Manager –> Create database and database user.
Enter the database name and the password that will be used for the user.
After creation, click on List Databases and users, you will see the database name and database user(created automatically)

Locate the Database section in the settings.py file and update it with the following.
By default, Django used SQLite, which you can use but we are using MySQL in this guide.

replace sqlite database backend

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

with Mysql database engine backend :

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
}
}

Save and close the file when you are finished.

ensure you've python mysqlclient installed

pip3.7 install mysqlclient

c) Complete Initial Project Setup
Now, we can migrate the initial database schema to our mysql database using the management script:

# cd /home/username/public_html
# python3.7 manage.py  makemigrations
# python3.7 manage.py  migrate

Create an administrative user for the project by typing:

# cd /home/username/public_html
# python3.7 manage.py createsuperuser

You will have to provide a username, an email address, and choose and confirm a password.

We can collect all of the static content into the directory location we configured by running the command:

# cd /home/username/public_html
# python3.7 manage.py collectstatic

Now, you can test your project by starting up the Django development server with the following command:

# cd /home/username/public_html
# python3.7 manage.py runserver 0.0.0.0:8000

In your web browser, visit http://server_domain_or_IP:8000 and you should see the default Django index page

4. Configure Apache and Nginx
CWP.Admin left Menu -> Webserver settings -> Webserver Domain Conf -> Select Username -> create configuration -> select the option - nginx->apache->proxy(custom port)

leave custom port as 8181 or you can change it.leave IP as 127.0.0.1, save changes.

a) Configure apache
Edit the vhost file for your domain in /usr/local/apache/conf.d/vhosts/ and add the following inside the virtual host container

WSGIScriptAlias / /home/username/public_html/myproj/wsgi.py
<Directory "/home/username/public_html/myproj">
<Files wsgi.py>
Require all granted
</Files>
</Directory>

Note : Please replace username and and project name(myproj) as per your setup as this is a guide.

Any request to Apache will execute the WSGI Script
To tell mod_wsgi how to handle the requests, modify the WSGI file located at /home/username/public_html/myproj/wsgi.py as per your setup:

import os
import sys #Add this
from django.core.wsgi import get_wsgi_application
sys.path.append('/home/username/public_html/') #Add this also
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproj.settings')
application = get_wsgi_application()

b) Configure Nginx
Edit the vhost file for your domain in /etc/nginx/conf.d/vhosts/ and add the following inside the server container

location /static/ {
root /home/username/public_html/;
expires 1d;
}

c) Restart Apache and Nginx services

 systemctl restart nginx httpd

d)In your web browser, visit http://yourdomain and you should see the default Django index page.
Django is running successfully and you can continue with creating Django applications.