Skip to content
Go back

How to Build a Machine Learning App with Django

How to Build a Machine Learning App with Django
Photo by pexels

Table of contents

Open Table of contents

Project Setup

Begin by setting up the project structure and installing dependencies.

Create a new directory and navigate into it:

mkdir django-house-price-app && cd django-house-price-app

Install required packages:

pip3 install Django scikit-learn pandas pickle

Initialize the Django project named houseapp and create an app called predictor:

django-admin startproject houseapp .
python3 manage.py startapp predictor

Create a templates directory:

mkdir -p templates/predictor

Now your project structure should look like this:

django-house-price-app/
├─ .venv/
├─ houseapp/
  ├─ __init__.py
  ├─ asgi.py
  ├─ settings.py
  ├─ urls.py
  └─ wsgi.py
├─ predictor/
  ├─ migrations/
  ├─ __init__.py
  ├─ apps.py
  ├─ forms.py       
  ├─ services.py     
  ├─ views.py        
  ├─ urls.py         
  └─ tests.py        
├─ templates/
  └─ predictor/
     └─ predict_form.html
├─ data/
  └─ Housing.csv     
├─ manage.py
├─ requirements.txt
└─ train_model.py     

Preparing the Dataset and Training the Machine Learning Model

We’ll use a kaggle dataset Housing.csv for house price prediction. It includes columns like area, bedrooms, bathrooms, stories, parking, and price. Place Housing.csv in a data/ directory.

Lets create train_model.py in the root to load the data, select features, train a Linear Regression model, and save it using pickle.

import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import pickle
from pathlib import Path

MODEL_DIR = Path("predictor") / "model"
MODEL_DIR.mkdir(parents=True, exist_ok=True)
MODEL_PATH = MODEL_DIR / "house_lr.pkl"

def main():
    df = pd.read_csv("data/Housing.csv")
    
    features = ['area', 'bedrooms', 'bathrooms', 'stories', 'parking']
    X = df[features]
    y = df['price']
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    
    model = LinearRegression()
    model.fit(X_train, y_train)
    
    # Save model
    with open(MODEL_PATH, 'wb') as f:
        pickle.dump(model, f)
    
    print(f"Saved model to {MODEL_PATH.resolve()}")

if __name__ == "__main__":
    main()data/train_model.py

After save the Run the script:

python3 data/train_model.py

This saves the trained model for use in the app.

Configure Django Settings

Update houseapp/settings.py to register the app and configure templates.

Add predictor to INSTALLED_APPS, include the templates directory, and set ALLOWED_HOSTS for development.

from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "predictor",  # <-- add
]

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [BASE_DIR / "templates"],  # <-- add
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

# For dev
ALLOWED_HOSTS = ["*"]houseapp/settings.py

Add URLs

Set up URL routing in houseapp/urls.py and create predictor/urls.py.

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

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("predictor.urls")),  # web routes
]houseapp/urls.py
from django.urls import path
from .views import home, predict_view

urlpatterns = [
    path("", home, name="home"),
    path("predict/", predict_view, name="predict"),
]predictor/urls.py

Build the Form

Create a form for user inputs in predictor/forms.py.

from django import forms

class HouseForm(forms.Form):
    area = forms.IntegerField(min_value=0, label="Area (sq ft)")
    bedrooms = forms.IntegerField(min_value=0, label="Bedrooms")
    bathrooms = forms.IntegerField(min_value=0, label="Bathrooms")
    stories = forms.IntegerField(min_value=0, label="Stories")
    parking = forms.IntegerField(min_value=0, label="Parking Spaces")predictor/forms.py

Load Model and Predict

In predictor/services.py, load the model and define a prediction function.

from pathlib import Path
import pickle
import numpy as np

_MODEL = None

def get_model():
    global _MODEL
    if _MODEL is None:
        model_path = Path(__file__).resolve().parent / "model" / "house_lr.pkl"
        with open(model_path, 'rb') as f:
            _MODEL = pickle.load(f)
    return _MODEL

def predict_house(features):
    """
    features: list[int] of length 5 (area, bedrooms, bathrooms, stories, parking)
    Returns predicted price.
    """
    model = get_model()
    X = np.array([features])
    price = model.predict(X)[0]
    return {"predicted_price": round(price, 2)}predictor/services.py

Views

Update predictor/views.py to handle the form and predictions.

from django.shortcuts import render
from django.views.decorators.http import require_http_methods
from .forms import HouseForm
from .services import predict_house

def home(request):
    return render(request, "predictor/predict_form.html", {"form": HouseForm()})

@require_http_methods(["POST"])
def predict_view(request):
    form = HouseForm(request.POST)
    if not form.is_valid():
        return render(request, "predictor/predict_form.html", {"form": form})
    data = form.cleaned_data
    features = [
        data["area"],
        data["bedrooms"],
        data["bathrooms"],
        data["stories"],
        data["parking"],
    ]
    result = predict_house(features)
    return render(
        request,
        "predictor/predict_form.html",
        {"form": HouseForm(), "result": result, "submitted": True},
    )predictor/views.py

Template

Create templates/predictor/predict_form.html with custom CSS for styling.

from django.shortcuts import render
from django.views.decorators.http import require_http_methods
from .forms import HouseForm
from .services import predict_house

def home(request):
    return render(request, "predictor/predict_form.html", {"form": HouseForm()})

@require_http_methods(["POST"])
def predict_view(request):
    form = HouseForm(request.POST)
    if not form.is_valid():
        return render(request, "predictor/predict_form.html", {"form": form})
    data = form.cleaned_data
    features = [
        data["area"],
        data["bedrooms"],
        data["bathrooms"],
        data["stories"],
        data["parking"],
    ]
    result = predict_house(features)
    return render(
        request,
        "predictor/predict_form.html",
        {"form": HouseForm(), "result": result, "submitted": True},
    )templates/predictor/predict_form.html

Running the Application

Apply migrations and start the server:

python3 manage.py migrate
python3 manage.py runserver

Visit http://127.0.0.1:8000/ to use the app. Enter house features and submit for predictions.

You’ve built a complete house price prediction app using Django and machine learning. From dataset preparation and model training to user interface design and deployment, this is simple project provides a practical foundation. Extend it with more features, advanced models, or datasets for production use. This is an excellent portfolio piece showcasing ML integration in web apps.


Share this post on:

Next Post
Build Graphql Api Strawberry Fastapi Sqlite