Open In App

Student Report Card in Django

In this Django project, we will develop a student report card system that displays individual subject marks, calculates the total marks obtained, and ranks students based on their performance. This project aims to provide a user-friendly platform for students to easily access and analyze academic data using Django. We’ll guide you through the implementation process in a few simple steps.

Student Report Card in Django

To install Django follow these steps.



Starting the Project Folder

To start the project use this command

django-admin startproject student
cd ecommerce

To start the app use this command



python manage.py startapp report

Register our app in settings.py file in the installed_apps sections like shown below.

INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"home",
"django_extensions",
]

Setting up the files

models.py: The code defines Django models for managing student information, departments, subjects, student IDs, subject marks, and report cards. It organizes student data and academic records within an educational institution, enabling relationships between students, departments, subjects, and their corresponding academic achievements and report cards.




from django.db import models
from django.contrib.auth.models import User
class Department(models.Model):
    department = models.CharField(max_length=100)
 
    def __str__(self) -> str:
        return self.department
 
    class Meta:
        ordering = ['department']
class StudentID(models.Model):
    student_id = models.CharField(max_length=100)
 
    def __str__(self) -> str:
        return self.student_id
class Subject(models.Model):
    subject_name = models.CharField(max_length=100)
     
    def __str__(self) -> str:
        return self.subject_name
class Student(models.Model):
    department = models.ForeignKey(Department, related_name='depart', on_delete=models.CASCADE)
    student_id = models.OneToOneField(StudentID, related_name="studentid", on_delete=models.CASCADE)
    student_name = models.CharField(max_length=100)
    student_email = models.EmailField(unique=True)
    student_age = models.IntegerField(default=18)
    student_address = models.TextField()
 
    def __str__(self) -> str:
        return self.student_name
 
    class Meta:
        ordering = ['student_name']
        verbose_name = "student"
class SubjectMarks(models.Model):
    student = models.ForeignKey(Student, related_name="studentmarks", on_delete=models.CASCADE)
    subject = models.ForeignKey(Subject , on_delete=models.CASCADE)
    marks = models.IntegerField()
     
    def __str__(self) -> str:
        return f'{self.student.student_name} - {self.subject.subject_name}'
 
    class Meta:
        unique_together = ['student', 'subject']
class ReportCard(models.Model):
    student = models.ForeignKey(Student, related_name="studentreportcard",  on_delete=models.CASCADE)
    student_rank = models.IntegerField()
    date_of_report_card_generation = models.DateField(auto_now_add=True)
     
    class Meta:
        unique_together = ['student_rank', 'date_of_report_card_generation']

views.py: The code essentially serves as a Django web application for managing and displaying student information, including their ranks and marks, with the ability to search for specific students. short the explanation not too much little bit




from django.shortcuts import render, redirect
from django.db.models import *
from .views import *
from .models import *
from django.http import HttpResponse
from django.contrib.auth.models import User
from django.contrib import messages
from django.core.paginator import Paginator
def get_student(request):
    queryset = Student.objects.all()
    ranks = Student.objects.annotate(marks=Sum('studentmarks__marks')).order_by('-marks', '-student_age')
    for rank in ranks:
        print(rank.marks)
    if request.GET.get('search'):
        search = request.GET.get('search')
        queryset = queryset.filter(
            Q(student_name__icontains=search) |
            Q(department__department__icontains=search) |
            Q(student_id__student_id__contains=search) |
            Q(student_email__icontains=search) |
            Q(student_age__icontains=search)
        )
        paginator = Paginator(queryset, 7)
    page_number = request.GET.get("page", 1)
    page_obj = paginator.get_page(page_number)
        print(page_obj.object_list)
         return render(request, 'students.html/', {'queryset': page_obj})
def see_marks(request, student_id):
    queryset = SubjectMarks.objects.filter(student__student_id__student_id=student_id)
        total_marks = queryset.aggregate(total_marks=Sum('marks'))
        current_rank = -1
        ranks = Student.objects.annotate(marks=Sum('studentmarks__marks')).order_by('-marks', '-student_age')
   
    i = 1
    for rank in ranks:
        if student_id == rank.student_id.student_id:
            current_rank = i
            break
        i = i + 1
        return render(request, 'see_marks.html/', {'queryset': queryset, 'total_marks': total_marks, 'current_rank': current_rank})

seed.py: The code includes functions to populate the database with random student data and subject marks.




from django.db.models import *
import sqlite3
from .models import *
import random
from faker import Faker
fake = Faker()
 
 
def create_subject_marks(n):
    try:
        student_objs = Student.objects.all()
        for student in student_objs:
            subjects = Subject.objects.all()
            for subject in subjects:
                SubjectMarks.objects.create(
                    subject=subject,
                    student=student,
                    marks=random.randint(0, 100)
                )
    except Exception as e:
        print(e)
 
 
def seed_db(n=10):
    try:
        for i in range(0, n):
            departments_objs = Department.objects.all()
            random_index = random.randint(0, len(departments_objs) - 1)
            department = departments_objs[random_index]
            student_id = f'STU-0{random.randint(100, 999)}'
            student_name = fake.name()
            student_email = fake.email()
            student_age = random.randint(20, 30)
            student_address = fake.address()
            student_id_obj = StudentID.objects.create(
                              student_id=student_id)
            student_obj = Student.objects.create(
                department=department,
                student_id=student_id_obj,
                student_name=student_name,
                student_email=student_email,
                student_age=student_age,
                student_address=student_address,
            )
    except Exception as e:
        print(e)
 
 
def generate_report_card():
    current_rank = -1
    ranks = Student.objects.annotate(
        marks=Sum('studentmarks__marks')).order_by('-marks',
                                                   '-student_age')
    i = 1
 
    for rank in ranks:
        ReportCard.objects.create(
            student=rank,
            student_rank=i
        )
        i = i + 1

admin.py: We register our app in admin.py file .




from django.contrib import admin
from .models import *
from django.db.models import Sum
admin.site.register(StudentID)
admin.site.register(Student)
admin.site.register(Department)
admin.site.register(Subject)
class SubjectMarkAdmin(admin.ModelAdmin):
    list_display = ['student', 'subject', 'marks']
admin.site.register(SubjectMarks, SubjectMarkAdmin)
class ReportCardAdmin(admin.ModelAdmin):
    list_display = ['student', 'student_rank', 'total_marks', 'date_of_report_card_generation']
    def total_marks(self, obj):
        subject_marks = SubjectMarks.objects.filter(student=obj.student)
        marks = subject_marks.aggregate(marks=Sum('marks'))
        return marks['marks']
    list_display += ['total_marks']
admin.site.register(ReportCard, ReportCardAdmin)

Creating GUI

students.html: This HTML file is used to view the students information.




{% extends "base.html" %}
 
{% block start %}
<!-- Include Bootstrap CSS -->
 
<!-- Container for the search form and student list -->
<div class="container mt-5">
    <!-- Search form -->
    <form action="" class="md-4">
        <div class="row">
            <div class="col-md-6">
                <input type="text" class="form-control" name="search" placeholder="Search">
            </div>
            <div class="col-md-6">
                <button class="btn btn-danger">Search</button>
            </div>
        </div>
    </form>
 
    <!-- Student list table -->
    <table class="table">
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">student_id</th>
                <th scope="col">Department</th>
                <th scope="col">student_name</th>
                <th scope="col">student_email</th>
                <th scope="col">student_age</th>
            </tr>
        </thead>
        <tbody>
            {% for student in queryset %}
            <tr>
                <!-- Counter for row numbers -->
                <th scope="row">{{ forloop.counter }}</th>
                 
                <!-- Link to see student marks, pointing to 'see_marks' URL with student ID -->
                <td> <a href="{% url 'see_marks' student.student_id  %}">
                    {{ student.student_id }}
                    </a></td>
                <td>{{ student.department.department }}</td>
                <td>{{ student.student_name }}</td>
                <td>{{ student.student_email }}</td>
                <td>{{ student.student_age }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
 
    <!-- Pagination navigation -->
    <nav aria-label="Page navigation example">
        <ul class="pagination">
            <!-- First and Previous Page links if available -->
            {% if queryset.has_previous %}
            <li class="page-item"><a class="page-link" href="?page=1">« first</a></li>
            <li class="page-item"><a class="page-link" href="?page={{ queryset.previous_page_number }}">previous</a>
            </li>
            {% endif %}
             
            <!-- Current Page and Total Page Count -->
            <li class="page-item disabled">
                <span class="page-link">
                    Page {{ queryset.number }} of {{ queryset.paginator.num_pages }}
                </span>
            </li>
             
            <!-- Next and Last Page links if available -->
            {% if queryset.has_next %}
            <li class="page-item"><a class="page-link" href="?page={{ queryset.next_page_number }}">next</a></li>
            <li class="page-item"><a class="page-link" href="?page={{ queryset.paginator.num_pages }}">last »</a>
            </li>
            {% endif %}
        </ul>
    </nav>
</div>
 
{% endblock %}

see_marks.html: This html file is used to view students marks.




{% extends "base.html" %}
 
{% block start %}
<!-- Include Bootstrap CSS -->
 
<!-- Container for displaying student marks -->
<div class="container mt-5">
    <!-- Display the student's rank and total marks -->
    <h4>Rank: {{ current_rank }}</h4>
    <h4>Total: {{ total_marks.total_marks }}</h4>
 
    <!-- Table to display subject-wise marks -->
    <table class="table">
        <tbody>
            {% for marks in queryset %}
            <tr>
                <!-- Counter for row numbers -->
                <th scope="row">{{ forloop.counter }}</th>
                 
                <!-- Display the subject name in bold -->
                <td><strong>{{ marks.subject.subject_name }}</strong></td>
                 
                <!-- Display the marks for the subject -->
                <td>{{ marks.marks }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</div>
 
{% endblock %}

base.html: This template can serve as a base for other templates, allowing them to inherit common styles and structures while customizing their content.




<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ page }}</title> <!-- Page title set dynamically -->
 
    <style>
        /* Styling for tables */
        table {
            width: 80%; /* Set table width */
            margin: 20px auto; /* Center-align the table and add some margin */
            border-collapse: collapse; /* Collapse table borders */
        }
 
        th,
        td {
            padding: 10px; /* Add padding to table cells */
            text-align: left; /* Left-align text within cells */
            border: 1px solid #ccc; /* Add a 1px solid border to cells */
        }
 
        th {
            background-color: #f2f2f2; /* Background color for table headers */
        }
 
        tr:nth-child(even) {
            background-color: #f2f2f2; /* Background color for even rows */
        }
 
        tr:hover {
            background-color: #ddd; /* Background color on hover */
        }
 
        /* Center the h1 text */
        h1.text-center {
            text-align: center; /* Center-align the h1 element */
        }
    </style>
</head>
 
<body>
    <!-- Navbar with the GeeksforGeeks title -->
    <nav class="navbar navbar-light bg-light justify-content-between shadow-lg">
        <h1 class="text text-center text-success mt-3 mx-auto"><strong> GeeksforGeeks</strong></h1>
    </nav>
 
    <!-- Content block to be filled by child templates -->
    {% block start %}
    {% endblock %}
 
    <!-- JavaScript script -->
    <script>
        console.log('Hey Django') // Example JavaScript code
    </script>
</body>
 
</html>

urls.py: Here we define all the URL pattern of the project.




from django.contrib import admin
from django.urls import path
from report.views import *
from django.conf.urls.static import static
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
    path("admin/", admin.site.urls),
    path('students/', get_student, name="get_student"),
    path('see-marks/<student_id>', see_marks, name="see_marks"),
]
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()

Deployement of the Project

Run these commands to apply the migrations:

python3 manage.py makemigrations
python3 manage.py migrate

Run the server with the help of following command:

python3 manage.py runserver

Output


Article Tags :