Last Updated : 23 Jul, 2025
We will build a Django app that lets users enter book details and download them as a formatted PDF. We’ll use Django for the form and data handling and ReportLab to generate the PDF file. Step-by-step, we will learn how to set up the project, create models and views and output a downloadable PDF catalog.
Create a New Django Project and AppPrerequisites:
Run the Following Command:
Register the Appdjango-admin startproject test_project
cd test_project
python manage.py startapp testapp
In test_project/settings.py, add your app to INSTALLED_APPS:
Create the ModelINSTALLED_APPS = [
...
'testapp',
]
testapp/models.py:
This code represents a simple Django model for storing information about books, including their title, author and publication year.
Python
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
publication_year = models.PositiveIntegerField()
def __str__(self):
return self.title
Create the Form
testapp/forms.py:
This code sets up a Django form, BookForm, that is connected to the Book model and includes specific fields for creating or editing book instances with title, author and publication year attributes.
Python
from django import forms
from .models import Book
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ['title', 'author', 'publication_year']
Create Views
testapp/views.py: Here is the code explanation of the views:
from django.http import FileResponse
from reportlab.pdfgen import canvas
from .models import Book
from django.shortcuts import redirect, render
from .forms import BookForm
def home(request):
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
form.save()
# Redirect to PDF generation after adding a book
return redirect('home')
else:
form = BookForm()
return render(request, 'myapp/create_user_profile.html',
{'form': form})
def generate_pdf(request):
response = FileResponse(generate_pdf_file(),
as_attachment=True,
filename='book_catalog.pdf')
return response
def generate_pdf_file():
from io import BytesIO
buffer = BytesIO()
p = canvas.Canvas(buffer)
# Create a PDF document
books = Book.objects.all()
p.drawString(100, 750, "Book Catalog")
y = 700
for book in books:
p.drawString(100, y, f"Title: {book.title}")
p.drawString(100, y - 20, f"Author: {book.author}")
p.drawString(100, y - 40, f"Year: {book.publication_year}")
y -= 60
p.showPage()
p.save()
buffer.seek(0)
return buffer
Set Up URLs
testapp/urls.p: This is to set in the URLs of the app.
Python
# test/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('generate-pdf/', views.generate_pdf, name='generate_pdf'),
]
test_project/urls.py: This is to set in the Urls of the project folder.
Python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('test.urls')),
]
Create Template
Directory structure:
testapp/
└── templates/
└── testapp/
└── create_user_profile.html
Create the template:
testapp/templates/testapp/create_user_profile.html
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Generate PDF</title>
</head>
<body>
<h1>Generate and Download PDF</h1>
<h2>Add a New Book</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Add Book</button>
</form>
<p><a href="{% url 'generate_pdf' %}" download>Download Book Catalog (PDF)</a></p>
<br>
<!-- <p><a href="{% url 'generate_pdf' %}" download>Download Book Catalog (CSV)</a></p> -->
</body>
</html>
Make and Apply Migrations
By the following commands you can migrate the data into the database.
Run the Serverpython manage.py makemigrations
python manage.py migrate
python manage.py runserver
Output:
Generate and Download PDFThe downloaded PDF:
Downloaded PDFRetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4