Introduction:
Django is a high-level web framework designed for rapid development and clean, pragmatic design. It’s built on Python and follows the model-template-view (MTV) architectural pattern, which separates application data, user interface, and business logic, making the codebase more organized and manageable.
Let’s build a plant identification web app. In this project, we’ll develop a web application using Django that allows users to upload images of plants for identification. With Django’s robust backend, we’ll handle image uploads and processing efficiently, leveraging an image recognition model to predict the plant species. Make sure Django is already installed. If it is not installed , run this in your terminal pip install Django.
Creating a project
run all the command lines that I provided below:
django-admin startproject plant_identifier cd plant_identifier python manage.py startapp plants
when you run all these you get a structure like this:

After this start writing code in files if any file is not created in the folder then create it manually. Example templates are not created here
create folder name templates inside the plants folder then again create folder name plants inside the templates inside it create HTML file name index.html we also need two images that we use to design the website. Put any two images in the folder which you want. Also, create a folder name styles inside it create a file name styles.css.
plant_identifier/settings.py
"""
Django settings for RABIS project.
Generated by 'django-admin startproject' using Django 3.1.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '#nxq5t82u#vg=7)65e8(yw#&vc2l0en@bap-*bjj0&a)%g0t)y'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'plants,
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'plant_identifier.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'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',
],
},
},
]
WSGI_APPLICATION = 'plant_identifier.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
# Base url to serve media files
MEDIA_URL = '/media/'
# Path where media is stored
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
plant_identifier/urls.py
"""RABIS URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', include('RAB.urls')),
path('admin/', admin.site.urls)
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
plant_identifier/wsgi.py
"""
WSGI config for RABIS project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'RABIS.settings')
application = get_wsgi_application()
plants/apps.py
from django.apps import AppConfig
class plantsConfig(AppConfig):
name = 'plants'
plants/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.index, name='index'),
path('predImg',views.predImg, name='predImg')
]
plants/views.py
from django.shortcuts import render
from django.core.files.storage import FileSystemStorage
from keras.models import load_model
from keras.preprocessing import image
from keras.preprocessing.image import img_to_array, load_img
from django.conf.urls import url
# Create your views here.
model = load_model('PId_Best.h5')
labels = ['daisy','dandelion','rose', 'sunflower', 'tulip']
img_heigh, img_with = 150, 150
def index(request):
context = {}
context["url"] = '/static/images/examp.jpg'
img_path = '.'+context["url"]
img = load_img(img_path, target_size = (img_heigh, img_with))
x = img_to_array(img)
x = x/255
x = x.reshape(1, img_heigh, img_with, 3)
pred = model.predict(x)
import numpy as np
context['predictedClass'] = labels[np.argmax(pred[0])]
context['probability'] = "{:.2f}".format(round(np.max(pred), 2)*100)
return render(request,'index.html',context)
def predImg(request):
if request.method == 'POST':
context = {}
uploaded_file= request.FILES['img']
fs = FileSystemStorage()
name = fs.save(uploaded_file.name, uploaded_file)
context["url"] = fs.url(name)
print(context["url"])
testimage = '.'+context["url"]
img = image.load_img(testimage, target_size=(img_heigh, img_with))
x = image.img_to_array(img)
x = x/255
x = x.reshape(1, img_heigh, img_with, 3)
pred = model.predict(x)
import numpy as np
context['predictedClass'] = labels[np.argmax(pred[0])]
context['probability'] = "{:.2f}".format(round(np.max(pred), 2)*100)
return render(request,'index.html',context)
plants/templates/plants/index.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="{% static 'styles/styles.css' %}">
<script src='https://kit.fontawesome.com/a076d05399.js'></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous">
</script>
<title>Plants Identification</title>
</head>
<body>
<!-- body style="background-image: background-image= url('{% static 'images/bodyimag.jpeg' %}');">-->
<table>
<tr>
<td>
<img class="img1"src="{% static 'images/logo.png' %}" title="Institut Scientifique de Rabat" />
</td>
<td>
<h1>PLANTS IDENTIFICATION </h1>
</td>
</tr>
</table>
<fieldset>
<legend class="leg1"> Plant Uploading <i class="fa fa-upload" style="font-size:20px;color:white"></i></legend>
<form method="post" enctype="multipart/form-data" action="predImg">
{% csrf_token %}
<table>
<tr>
<td>
<table>
<tr>
<td></td><td> <input type ="file" required name ="img" id ="img" class="inputfile"></td>
</tr>
<tr>
<td></td> <td> <button type ="submit" name="predict" value= "Predict" title="Click here to predict">PREDICT <i class='fas fa-chart-line' style='font-size:20px;color:white'></i></button></td>
</tr>
</table>
</td>
<td>
</td>
<td>
<p class ='tip'>
<i class='far fa-bell' style='font-size:20px;color:red'></i>
For an accurate identification, please upload a high-quality image with excellent resolution without noise in the background as shown here <a href="http://127.0.0.1:8000/"> <i class='fas fa-code' style='font-size:15px;color:#008CBA'></i> </a>
</p>
</td>
</tr>
</table>
</form>
</fieldset>
<fieldset>
<legend class= "leg2"> Plant Prediction <i class='fab fa-codiepie' style='font-size:20px;color:white'></i> </legend>
<table>
<tr>
<td>
</td>
<td>
{% if url %}
<img class="img2"src="{{ url }}" />
{% endif %}
</td>
<td>
<td>
</td>
<td>
<div class="Div"><i class="fa fa-sitemap" style="font-size:20px;color:white"></i> PLANT'S CLASS IS : </div>
<div class="Div" id="Div1"><span> <i class="fa fa-magic" style="font-size:20px;color:white"></i> {{predictedClass}}</span></div>
</td>
<td>
<div class="Div"><i class='fas fa-gavel' style='font-size:20px;color:white'></i> THE PROBABILITY : </div>
<div class="Div" id="Div1"><span> <i class='fas fa-drafting-compass' style='font-size:20px;color:white'></i> {{probability}} %</span></div>
</td>
</tr>
</table>
</fieldset>
</body>
<footer>
<div id="footer">
© All rights reserved IS DBEV, UM5 de Rabat
<span class="nz">DEVELOPER : Nour Edd<a href="https://www.linkedin.com/in/nour-eddine-zekaoui-ba43b1177/"><i class='fab fa-linkedin' style='font-size:15px;color:white'></i></a>e ZEKAOUI </span>
</div>
</footer>
</html>
After doing all these run the command python manage.py migrate in your terminal after running this command line you get this
System check identified no issues (0 silenced).
November 07, 2024 – 18:20:45
Django version 5.0.1, using settings ‘plant_identifier.settings’
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
After doing this click on the link and you get your webpage
webpage:
