• In one shot we can complete module 4's two programs.
  • Now follow the instructions carefully, the only thing we have to do is to edit the previously existing files in order to get the output, So change the below files contents.

No changes in models.py and admin.py so don't alter them.

Edit views.py

  • Rewrite the whole views.py file with the below contents.
from django.shortcuts import render, redirect, HttpResponse, get_object_or_404
from django.contrib import messages
from .models import Student, Course
from django.views.generic import ListView, DetailView
from django.views import View
import csv
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
import io


# Create your views here.
def test(request):
    return HttpResponse("this is a test")


def register(request):
    if request.method == 'POST':
        student_name = request.POST['name']
        student_email = request.POST['email']
        course_id = request.POST['course']
        course = Course.objects.get(pk=course_id)
        student, created = Student.objects.get_or_create(name=student_name, email=student_email)
        course.students.add(student)
        messages.success(request, 'Student successfully added to the course.')
        return redirect('register')
    else:
        courses = Course.objects.all()
        return render(request, 'register.html', {'courses': courses})

def registered(request, course_title):
    course = get_object_or_404(Course, title=course_title)
    students = course.students.all()
    return render(request, 'registered.html', {'course': course, 'students': students})


# generic class view


class StudentListView(ListView):
    model = Student
    template_name = 'student_list.html'  # Specify your template name/location
    context_object_name = 'students'  # Name to use for the list of objects in the template

class StudentDetailView(DetailView):
    model = Student
    template_name = 'student_detail.html'  # Specify your template name/location
    context_object_name = 'student'  # Name to use for the single object in the template



# for csv file generation

class ExportCSVView(View):
    def get(self, request):
        # Create the HttpResponse object with the appropriate CSV header.
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="students.csv"'

        writer = csv.writer(response)
        writer.writerow(['Name', 'Email'])

        students = Student.objects.all()
        for student in students:
            writer.writerow([student.name, student.email])

        return response


# for pdf generation

class ExportPDFView(View):
    def get(self, request):
        # Create the HttpResponse object with the appropriate PDF header.
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="students.pdf"'

        buffer = io.BytesIO()
        p = canvas.Canvas(buffer, pagesize=letter)
        p.setFont("Helvetica", 12)

        students = Student.objects.all()
        y = 750
        for student in students:
            p.drawString(30, y, f"Name: {student.name}, Email: {student.email}")
            y -= 20

        p.showPage()
        p.save()

        buffer.seek(0)
        return HttpResponse(buffer, content_type='application/pdf')

Edit the urls.py file

  • Rewrite the whole urls.py file as below.
from django.urls import path,include
from . import views
from .views import StudentListView, StudentDetailView
from .views import ExportCSVView , ExportPDFView


urlpatterns = [
    path('test/',views.test,name="test"),
    path('register/',views.register,name="register"),
    # path('registered/<int:course_id>/',views.registered,name="registered"),
    path('registered/<str:course_title>/', views.registered, name='registered'),
    # urls for generice class view
    path('students/', StudentListView.as_view(), name='student_list'),
    path('students/<int:pk>/', StudentDetailView.as_view(), name='student_detail'),
    # urls for csv and pdf generation
    path('export/csv/', ExportCSVView.as_view(), name='export_csv'),
    path('export/pdf/', ExportPDFView.as_view(), name='export_pdf'),


]

Add these html files in the templates directory.

  • base.html, student_detail.html, and student_list.html
  • In base.html
<!DOCTYPE html>
<html>
<head>
    <title>Student Course Project</title>
</head>
<body>
    <h1>Student Course Project</h1>
    <ul>
        <li><a href="{% url 'export_csv' %}">Export Students to CSV</a></li>
        <li><a href="{% url 'export_pdf' %}">Export Students to PDF</a></li>
    </ul>
</body>
</html>
  • In student_detail.html
<!DOCTYPE html>
<html>
<head>
    <title>Student Details</title>
</head>
<body>
    <h2>Student Details</h2>
    <p><strong>Name:</strong> {{ student.name }}</p>
    <p><strong>Email:</strong> {{ student.email }}</p>
    <p><strong>Courses:</strong></p>
    <ul>
        {% for course in student.courses.all %}
            <li>{{ course.title }}</li>
        {% endfor %}
    </ul>
    <a href="{% url 'student_list' %}">Back to Student List</a>
</body>
</html>
  • In student_list.html.
<!DOCTYPE html>
<html>
<head>
    <title>Student List</title>
</head>
<body>
    <h2>Student List</h2>
    <ul>
        {% for student in students %}
            <li><a href="{% url 'student_detail' student.pk %}">{{ student.name }}</a></li>
        {% endfor %}
    </ul>
</body>
</html>

Install the required modules

  • Before running the live server install the required modules.
  • pip3 install reportlab

See the output

  • See the output by reffering the urls.py files urls.

Resourses

Watch a quick video summary on how to run this program

Watch it at 2x speed