In this lesson, we will build a practical Django Student Management Project. This project combines many concepts learned in previous lessons, including models, ModelForms, CRUD operations, authentication, search, pagination, templates, URLs, and the Django admin panel.
A student management system can be used by schools, colleges, coaching institutes, and training centers to manage student information.
A Student Management System is a web application used to store and manage student information.
A basic system can manage:
Our basic student management project can contain the following features:
First, create a Django project.
django-admin startproject school_project
Move into the project directory:
cd school_project
Start the development server:
python manage.py runserver
Create an application called students.
python manage.py startapp students
Add it to INSTALLED_APPS:
INSTALLED_APPS = [
...
"students",
]
The Student model stores student information in the database.
from django.db import models
class Student(models.Model):
name = models.CharField(
max_length=100
)
email = models.EmailField()
mobile = models.CharField(
max_length=15
)
course = models.CharField(
max_length=100
)
age = models.IntegerField()
admission_date = models.DateField(
auto_now_add=True
)
def __str__(self):
return self.name
After creating the model, create a migration.
python manage.py makemigrations
Then apply the migration:
python manage.py migrate
Django will create the required database table.
Create students/forms.py to simplify student data entry.
from django import forms
from .models import Student
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = [
"name",
"email",
"mobile",
"course",
"age"
]
The ModelForm automatically creates form fields based on the model.
The list view retrieves all students from the database.
from django.shortcuts import render
from .models import Student
def student_list(request):
students = Student.objects.all().order_by(
"name"
)
return render(
request,
"students/student_list.html",
{
"students": students
}
)
The create view allows users to add a new student.
from django.shortcuts import redirect
from .forms import StudentForm
def student_create(request):
if request.method == "POST":
form = StudentForm(
request.POST
)
if form.is_valid():
form.save()
return redirect(
"student_list"
)
else:
form = StudentForm()
return render(
request,
"students/student_form.html",
{
"form": form
}
)
Create student_form.html.
<h2>Add Student</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button
type="submit"
>
Save Student
</button>
</form>
The CSRF token protects the POST form from cross-site request forgery.
The list template displays student information in a table.
<h2>Student List</h2>
<a href="{% url 'student_create' %}">
Add Student
</a>
<table>
<tr>
<th>Name</th>
<th>Email</th>
<th>Mobile</th>
<th>Course</th>
<th>Age</th>
<th>Action</th>
</tr>
{% for student in students %}
<tr>
<td>
{{ student.name }}
</td>
<td>
{{ student.email }}
</td>
<td>
{{ student.mobile }}
</td>
<td>
{{ student.course }}
</td>
<td>
{{ student.age }}
</td>
<td>
<a href="{% url 'student_update' student.id %}">
Edit
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="6">
No students found.
</td>
</tr>
{% endfor %}
</table>
A detail view can display complete information about one student.
from django.shortcuts import get_object_or_404
def student_detail(request, id):
student = get_object_or_404(
Student,
id=id
)
return render(
request,
"students/student_detail.html",
{
"student": student
}
)
<h2>
Student Details
</h2>
<p>
Name:
{{ student.name }}
</p>
<p>
Email:
{{ student.email }}
</p>
<p>
Mobile:
{{ student.mobile }}
</p>
<p>
Course:
{{ student.course }}
</p>
<p>
Age:
{{ student.age }}
</p>
<p>
Admission Date:
{{ student.admission_date }}
</p>
The update view loads the existing student into the ModelForm.
def student_update(request, id):
student = get_object_or_404(
Student,
id=id
)
if request.method == "POST":
form = StudentForm(
request.POST,
instance=student
)
if form.is_valid():
form.save()
return redirect(
"student_list"
)
else:
form = StudentForm(
instance=student
)
return render(
request,
"students/student_form.html",
{
"form": form,
"student": student
}
)
The delete view removes a student after a POST request.
def student_delete(request, id):
student = get_object_or_404(
Student,
id=id
)
if request.method == "POST":
student.delete()
return redirect(
"student_list"
)
return render(
request,
"students/student_confirm_delete.html",
{
"student": student
}
)
The student list can be enhanced with a search box.
query = request.GET.get(
"q",
""
).strip()
students = Student.objects.all()
if query:
students = students.filter(
name__icontains=query
)
students = students.order_by(
"name"
)
Now students can be searched by name.
<form method="get">
<input
type="text"
name="q"
value="{{ query }}"
placeholder="Search student"
>
<button type="submit">
Search
</button>
</form>
The GET parameter can be read using
request.GET.get("q").
If there are many students, pagination can be added to the student list.
from django.core.paginator import Paginator
paginator = Paginator(
students,
10
)
page_number = request.GET.get(
"page"
)
page_obj = paginator.get_page(
page_number
)
The template can display page_obj instead of all students.
{% if page_obj.has_previous %}
<a href="?q={{ query }}&page={{
page_obj.previous_page_number
}}">
Previous
</a>
{% endif %}
<span>
Page {{ page_obj.number }}
of
{{ page_obj.paginator.num_pages }}
</span>
{% if page_obj.has_next %}
<a href="?q={{ query }}&page={{
page_obj.next_page_number
}}">
Next
</a>
{% endif %}
Messages can tell the user when an operation has completed successfully.
from django.contrib import messages
form.save()
messages.success(
request,
"Student added successfully."
)
return redirect(
"student_list"
)
Similar messages can be added for update and delete operations.
Create students/urls.py.
from django.urls import path
from . import views
urlpatterns = [
path(
"",
views.student_list,
name="student_list"
),
path(
"add/",
views.student_create,
name="student_create"
),
path(
"<int:id>/",
views.student_detail,
name="student_detail"
),
path(
"<int:id>/edit/",
views.student_update,
name="student_update"
),
path(
"<int:id>/delete/",
views.student_delete,
name="student_delete"
),
]
Include the student URLs in the main project's
urls.py.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(
"admin/",
admin.site.urls
),
path(
"students/",
include("students.urls")
),
]
The student management pages will now be available under the
/students/ path.
Register the Student model in students/admin.py.
from django.contrib import admin
from .models import Student
admin.site.register(
Student
)
The Student model will now appear in the Django admin panel.
The admin panel can be customized using ModelAdmin.
from django.contrib import admin
from .models import Student
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
list_display = (
"name",
"email",
"mobile",
"course",
"age",
"admission_date"
)
search_fields = (
"name",
"email",
"mobile",
"course"
)
list_filter = (
"course",
"admission_date"
)
school_project/
│
├── manage.py
│
├── school_project/
│ ├── settings.py
│ ├── urls.py
│ ├── asgi.py
│ └── wsgi.py
│
└── students/
├── migrations/
├── templates/
│ └── students/
│ ├── student_list.html
│ ├── student_form.html
│ ├── student_detail.html
│ └── student_confirm_delete.html
│
├── __init__.py
├── admin.py
├── apps.py
├── forms.py
├── models.py
├── urls.py
├── views.py
└── tests.py
from django.shortcuts import render
from django.core.paginator import Paginator
from .models import Student
def student_list(request):
query = request.GET.get(
"q",
""
).strip()
students = Student.objects.all()
if query:
students = students.filter(
name__icontains=query
)
students = students.order_by(
"name"
)
paginator = Paginator(
students,
10
)
page_number = request.GET.get(
"page"
)
page_obj = paginator.get_page(
page_number
)
return render(
request,
"students/student_list.html",
{
"page_obj": page_obj,
"query": query
}
)
A real student management system may need authentication so that only authorized users can manage student records.
Django provides the login_required decorator.
from django.contrib.auth.decorators import login_required
@login_required
def student_list(request):
students = Student.objects.all()
return render(
request,
"students/student_list.html",
{
"students": students
}
)
The same approach can be applied to create, update, and delete views.
Student Model
↓
Database Migration
↓
ModelForm
↓
Student List
↓
Add Student
↓
View Details
↓
Edit Student
↓
Delete Student
↓
Search
↓
Pagination
↓
Messages
↓
Authentication
↓
Admin Panel
The basic project can be expanded into a complete education management system.
The Student Management Project brings together many important Django concepts into one practical application.
Question: Which Django feature is commonly used to create forms directly from a model?