How to deploy Machine Learning Models on Django

Agnes Mbiti
6 min readMar 2, 2023

--

If you have encountered machine learning models, you must have wondered how to share your fun project with a larger audience. Since most of these models are trained in Jupyter Notebook, Django is one of Pythons’ frameworks that comes in handy when we want to deploy them on the web. In this article, we are going to follow a series of simple steps and set up our model in a Django application.

Prerequisites.

Django 3.2.3

scikit-learn 1.0.2

pandas 1.3.5

Django project.

First, we have to set up a Django application. Run the command below in the terminal to create our Django project in the directory you want your project in.

django-admin startproject practice

The above command creates a new folder in the root directory. The structure of the new folder should look like the block below

practice/
manage.py
practice/
__init__.py
settings.py
urls.py
wsgi.py
asgi.py

While inside the practice directory ,you can start your development server by running the command below in the terminal

$ python manage.py runserver

Your development server, at this point, should look similar to the picture below.

Django development server

Now that your project is set up, let’s create the Django app. We do this by running the command below in the terminal

$ python manage.py startapp practiceApp

A new folder should appear in our root directory. The contents inside this new folder should match the block below

practiceApp/
migrations/
__init__.py
__init__.py
admin.py
apps.py
models.py
tests.py
views.py

We are going to add a urls.pyfile in the practiceApp directory. The file structure in the two created directories is not the same.

In your settings.py the practice directory, add your practiceApp app in the INSTALLED_APPS segment, just like shown in the snippet below

practice/settings.py

INSTALLED_APPS

It is one of the ways we use to link our Django project and app.

Next, we create our templates directory in our projects’ root folder. Once that is done, we will create a index.html file inside it. We will use this file to define a simple front-end for our application.

The model

Still, in our root folder, let’s create a model folder. Let’s create a model.ipynb file inside this folder. This file will differ from our .py files since it’s in jupyter notebook format. We use jupyter notebook to analyze data/code as we go. Once our file is opened, add the code block below in our first code cell to load our iris dataset.

from sklearn.datasets import load_iris
import pandas as pd

data = load_iris()
X_data = pd.DataFrame(data.data, columns = data.feature_names)
y_data = pd.Series(data = data.target, name = 'Targets')
X_data.head()

As you can see from the block above, we can load and get the first five rows of the dataset. Your output should look like the snippet below.

first five rows output

Next, we use the train_test_split method to divide the data into training and testing data. Once that is done, we import the RandomForestClassifier model to train our data. Here, we use our training data, X_train and Y_train, and fit it into our model. Fitting models highly increases the chances of better results/predictions. All this is shown in the code block below

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size = 0.2)
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X_train, y_train)

After that, we measure our models’ accuracy score, and if we are satisfied with the result, we proceed to the next task. In this case, our model got a 96% accuracy score, as shown below.

y_pred = model.predict(X_test)
from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_pred)

Once you run the above cell, the output displays a 0.9666666666666667 accuracy score, telling us that our model is 96% more likely to give us better predictions.

Lastly, we need to save our model as a joblib file to import it into our project views file later and use it to make simple predictions. JoblibTo do this, we create a new empty directory at our project root. We can give it the name modelSaved. We then return to our main.ipynb file and run the code block below in the last code cell.

from joblib import dump
dump(model, './savedModel/model.joblib')

Remember to change the relative path to match that of your savedModel directory. When you look at your savedModel directory, there is a new model.joblib file. Our model is now saved and ready to be integrated into our application.

Another mandatory step to connect our app and project directories is to link our URLs. We do this by including the practiceApp URLs in our project URLs, in this case, the practice URL. Below is how we can make this happen.

practice/urls.py

from django.urls import path, include

urlpatterns = [
path('', include('practiceApp.urls')),
]

In our practiceApp URLs, we add URL patterns that show our app views. It is where we call the functions defined in our view file. It is shown in the code block below

practiceApp/urls.py

from django.urls import path
from . import views

urlpatterns = [
path('', views.predictor, name = 'predictor'),
]

Let’s see what the predictor function looks like in our views.pyfile.

practiceApp/views.py

from django.shortcuts import render

from joblib import load
model = load('./savedModel/model.joblib')

def predictor(request):
if request.method == 'POST':
sepal_length = request.POST['sepal_length']
sepal_width = request.POST['sepal_width']
petal_length = request.POST['petal_length']
petal_width = request.POST['petal_width']
y_pred = model.predict([[sepal_length, sepal_width, petal_length, petal_width]])
if y_pred[0] == 0:
y_pred = 'Setosa'
elif y_pred[0] == 1:
y_pred = 'Verscicolor'
else:
y_pred = 'Virginica'
return render(request, 'index.html', {'result' : y_pred})
return render(request, 'index.html')In our view file, we started by loading our already saved model. We then defined a predictor function that makes use of the POST method. In our prediction method, we wrote a short loop for our y_pred, which is also the user input to determine the prediction. All the output is based on the trained model prediction. Then, finally, our result, which will be later referenced in our index.html file, is given as the value of y_pred, in short, the user input.
from joblib import load
model = load('./savedModel/model.joblib')

In our view file, we started off by loading our already saved model. We then defined a predictor function that makes use of the POST method. In our prediction method, we wrote a short loop for our y_pred, also the user input, to determine exactly what the prediction would be. All the output is based on the trained model prediction. Then finally, our result ,that will be later referenced in our index.html file , is given as the value of y_pred , in short, the user input.

Front-end

In our index.html file, paste the following HTML code

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> Django </title>
</head>
<body>
<h1>Iris Application</h1>
<hr>
{% if result %}
<h1>Flower is {{result}}</h1>
{% endif %}

<form action="" method="POST">
{% csrf_token %}
Sepal Length : <input type="number" name="sepal_length" required><br>
Sepal Width : <input type="number" name="sepal_width" required><br>
Petal Length : <input type="number" name="petal_length" required><br>
Petal Width : <input type="number" name="petal_width" required><br>
<input type="submit">
</form>
</body>
</html>

The above html code creates a simple form that is going to enable a user test our model. Once you run your development server, you should be able to get different output based on your form input.

Conclusion

So far, you have successfully deployed a machine-learning model in your Django application. Building the front-end aspects of your model makes it easier for it to reach a bigger and wider audience.

--

--