Open In App

E-book Library using Django

Last Updated : 29 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will demonstrate how to build an E-book Library using Django. We have incorporated the functionality of login and registration, ensuring that users must first log in and register to access and read books. Additionally, after logging in, users gain the capability to both read and add books. They are granted the privilege to update and delete the books they have added. It’s important to note that other users while having the ability to read books, are restricted from editing or deleting books created by fellow users. This security measure ensures that users can only manipulate their content within the E-book Library.

E-book Library Using Django

To install Django follow these steps.

Starting the Project Folder

To start the project use this command

django-admin startproject elibrary_project
cd elibrary_project

To start the app use this command

python manage.py startapp elibrary_app

Now add this app to the ‘settings.py’

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

File Structure

files

Setting Necessary Files

models.py: Here, the Django model defines an “EBooksModel” with fields for title, summary, page count, PDF file upload, author name, category, and author ID. The “__str__” method specifies the string representation of an instance, returning the title. The model is intended for an E-book Library, allowing storage and retrieval of book information.

Python3




from django.db import models
 
# Create your models here.
class EBooksModel(models.Model):
  
    title = models.CharField(max_length = 80)
    summary = models.TextField(max_length=2000)
    pages = models.CharField(max_length=80)
    pdf = models.FileField(upload_to='pdfs/')
    author = models.CharField(max_length=80)
    category = models.CharField(max_length=80)
    author_id = models.IntegerField(default=0)
 
    def __str__(self):
        return f"{self.title}"


views.py: Here, the provided Django views comprise a web application for an E-book Library. The “Registers” view manages user registration, “Login” handles user authentication, and “home” renders the home page. The “explore” view categorizes and displays books. “addBook” lets logged-in users contribute books, and “contri” shows books contributed by a user. “logout” logs out users, “deleteBook” removes a book, and “editBook” enables book editing. “viewBook” displays detailed information about a specific book, formatted for readability. The application emphasizes user authentication, book contribution, and management functionalities.

Python3




from django.shortcuts import redirect, render
from elibrary_app.forms import EBooksForm
from elibrary_app.models import EBooksModel
from django.contrib.auth.models import User,auth
from django.contrib.auth.decorators import login_required
from django.contrib import messages
 
# Create your views here.
def Registers(request):
    if request.method == 'POST':
        email = request.POST['email']
        password = request.POST['password']
        firstName = request.POST['first--name']
        lastName = request.POST['last--name']
 
        # Check if a user with the same username already exists
        if User.objects.filter(username=email).exists():
            messages.info(request,'User already exists')
            return render(request, 'register.html')
        else:
            # Create a new user
            register = User.objects.create_user(username=email,password=password,first_name=firstName,last_name=lastName)
            # No need to call save() after create_user(), as it's already saved
            return redirect('login')
    else:
        return render(request, 'register.html')
     
 
def Login(request):
    if request.method == 'POST':
        email = request.POST['email']
        password = request.POST['password']
 
        user = auth.authenticate(username=email, password=password)
 
        if user is not None:
            auth.login(request, user)
            print('User logged in successfully')
            return redirect('home')
        else:
            messages.info(request,'Invalid Credentials')
            return render(request, 'login.html')
    else:
        return render(request, 'login.html')
 
def home(request):
   return render(request, 'home.html')
 
def explore(request):
    edu_books = EBooksModel.objects.filter(category='Education')
    fiction_books = EBooksModel.objects.filter(category='Fiction')
    science_books = EBooksModel.objects.filter(category='Science')
    return render(request, 'explore.html',{'edu_books':edu_books,'fiction_books':fiction_books,'science_books':science_books})
 
@login_required
def addBook(request,user_id):
    user = User.objects.get(id=user_id)
    if request.method == 'POST':
        form = EBooksForm(request.POST, request.FILES)
        if form.is_valid():
            book = form.save(commit=False)
            book.author = user.first_name + " " + user.last_name
            book.author_id = user.id
            print(book.author)
            book.save()
            print()
            print()
            print(book.author)
            print("Book saved successfully")
            print()
            print()
            return redirect('home')
        else:
            print(form.errors)
    else:
        form = EBooksForm()
    return render(request, 'addBook.html', {'form': form})
 
def contri(request,user_id):
    books = EBooksModel.objects.filter(author_id=user_id)
    return render(request, 'contri.html', {'books': books})
 
 
def logout(request):
    auth.logout(request)
    return redirect('home')
 
def deleteBook(request,book_id):
    book = EBooksModel.objects.get(id=book_id)
    book.delete()
    return redirect('home')
 
def editBook(request,book_id):
    book = EBooksModel.objects.get(id=book_id)
    if request.method == 'POST':
        form = EBooksForm(request.POST, request.FILES,instance=book)
        if form.is_valid():
            form.save()
            print()
            print()
            print("Book updated successfully")
            print()
            print()
            return redirect('home')
        else:
            print(form.errors)
    else:
        form = EBooksForm(instance=book)
    return render(request, 'editBook.html', {'form': form,'book':book})
 
def viewBook(request,book_id):
    book = EBooksModel.objects.get(id=book_id)
    book.summary = book.summary.replace('\n', '<br/>')
    return render(request, 'viewBook.html', {'book': book})


forms.py : Here ,the “EBooksForm” in Django defines a form for inputting book details, associated with the “EBooksModel.” It includes fields for title, summary, pages, PDF file, and category, with category options like Education, Fiction, and Science. The form uses Bootstrap classes for styling and sets all fields as required for complete submission, making it suitable for creating or editing book instances in the E-book Library.

Python3




from django import forms
from .models import EBooksModel
 
class EBooksForm(forms.ModelForm):
    CATEGORY_CHOICES = [
        ('Education', 'Education'),
        ('Fiction', 'Fiction'),
        ('Science', 'Science'),
        # Add more categories as needed
    ]
 
    category = forms.ChoiceField(choices=CATEGORY_CHOICES)
 
    class Meta:
        model = EBooksModel
        fields = ['title', 'summary', 'pages', 'pdf', 'category']
 
    def __init__(self, *args, **kwargs):
        super(EBooksForm, self).__init__(*args, **kwargs)
        self.fields['title'].widget.attrs.update({'class': 'form-control', 'placeholder': 'Enter title'})
        self.fields['summary'].widget.attrs.update({'class': 'form-control', 'placeholder': 'Enter summary'})
        self.fields['pages'].widget.attrs.update({'class': 'form-control', 'placeholder': 'Enter pages'})
        self.fields['pdf'].widget.attrs.update({'class': 'form-control', 'placeholder': 'Enter pdf'})
        self.fields['category'].widget.attrs.update({'class': 'form-control', 'placeholder': 'Select category'})
         
        # Make all fields required
        for field_name, field in self.fields.items():
            field.required = True


elibrary_app/urls.py : Here, the code defines URL patterns in a Django application, linking specific paths to corresponding views. For instance, an empty path leads to the ‘home’ view, ‘explore’ to the ‘explore’ view, ‘register’ to ‘Registers,’ and ‘login’ to ‘Login.’ Dynamic paths like ‘addBook’ and ‘contri’ include parameters for handling user-specific data, establishing a structured routing system for the web application.

Python3




from django.urls import path
from . import views
 
urlpatterns = [
  path('', views.home, name='home'),
  path('explore', views.explore, name='explore'),
  path('register', views.Registers, name='register'),
  path('login', views.Login, name='login'),
  path('addBook/<int:user_id>', views.addBook, name='addBook'),
  path('addBook', views.addBook, name='addBook'),
  path('contri/<int:user_id>', views.contri, name='contri'),
  path('logout', views.logout, name='logout'),
  path('deleteBook/<int:book_id>', views.deleteBook, name='deleteBook'),
  path('editBook/<int:book_id>', views.editBook, name='editBook'),
  path('viewBook/<int:book_id>', views.viewBook, name='viewBook'),
]


elibrary_project/urls.py : Here , the Django URL configuration includes paths for the admin panel and incorporates URLs from the “elibrary_app.urls” module. Additionally, in debug mode, it appends a pattern to serve media files based on the settings for media URL and root, facilitating media file access during development.

Python3




from django.conf import settings # new
from django.conf.urls.static import static # new
from django.contrib import admin
from django.urls import path,include # new
 
urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("elibrary_app.urls")), # new
]
 
if settings.DEBUG or not settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


Creating GUI (templates)

addBook.html : This HTML template incorporates Bootstrap for styling, featuring a navigation bar, an “Add Book” section with a form posting to the ‘addBook’ URL, and a simple footer. The form includes a CSRF token, and static files (‘style.css’ and ‘addBook.css’) enhance the design. The JavaScript bundle from Bootstrap ensures responsive behavior in the navigation bar.

HTML




{% load static %}
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <link rel="stylesheet" href="{% static 'css/style.css' %}"/>
    <link rel="stylesheet" href="{% static 'css/addBook.css' %}"/>
</head>
  <body>
    <!-- Navbar -->
    <section class="navbar--section">
      <nav class="navbar navbar-expand-lg ">
        <div class="container-fluid">
          <a class="navbar-brand" href="#">E-Library</a>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse justify-content-end" id="navbarNav">
            <ul class="navbar-nav">
              <li class="nav-item">
                <a class="active nav-link " aria-current="page" href="/">Home</a>
              </li>
            </ul>
          </div>
        </div>
      </nav>
    </section>
 
    <!-- Add Book -->
    <section class="add--section">
        <form method="post" action="{% url 'addBook' user.id %}" enctype="multipart/form-data">
 
            {% csrf_token %}
            {{form}}
             
            <button type="submit" class="btn btn-primary mt-3">Add Book</button>
        </form>
    </section>
   
 
    <!-- Footer -->
    <section class="footer--section">
      <div class="container-fluid text-center">
        <div class="footer--items row">
          <div class="footer--details col-lg-12">
            <p>© 2023 E-Library. All rights reserved.</p>
          </div>
        </div>
 
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
  </body>
</html>


contri.html : This HTML template utilizes Bootstrap for styling, showcasing a navigation bar and a “View Book” section that dynamically displays contributed books with details. It incorporates static files for custom styles, includes buttons for actions like viewing, deleting, and editing books, and ensures responsiveness using Bootstrap’s JavaScript bundle.

HTML




{% load static %}
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <link rel="stylesheet" href="{% static 'css/style.css' %}"/>
    <link rel="stylesheet" href="{% static 'css/contri.css' %}"/>
    <style>
      *{
        box-sizing: border-box;
        margin: 0;
      }
    </style>
</head>
  <body>
    <!-- Navbar -->
    <section class="navbar--section">
      <nav class="navbar navbar-expand-lg ">
        <div class="container-fluid">
          <a class="navbar-brand" href="#">E-Library</a>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse justify-content-end" id="navbarNav">
            <ul class="navbar-nav">
              <li class="nav-item">
                <a class="active nav-link " aria-current="page" href="/">Home</a>
              </li>
            </ul>
          </div>
        </div>
      </nav>
    </section>
 
    <!-- View Book -->
    <section class="contri--section">
      <div class="container">
            <div class="row">
               
             
        {% for book in books %}
         
                  <div class="col-lg-4 ">
                    <div class="card" style="height: 300px;">
                    <div class="card-body">
                        <h5 class="card-title text-center mb-3">{{book.title}}</h5>
                        <p class="card-text">Description : {{ book.summary|truncatechars:50 }}</p>
                        <p class="card-text">Pages : {{book.pages}}</p>
                        <p class="card-text">Category : {{book.category}}</p>
                        <p class="card-text">Contributed By : {{book.author}}</p>
 
                        <a href="{{book.pdf.url}}" class="btn btn-primary">View Book</a>
                        <a href="{% url 'deleteBook' book.id %}" class="btn btn-danger">Delete Book</a>
                        <a href="{% url 'editBook' book.id %}" class="btn btn-danger">Edit Details</a>
                    </div>
                  </div>
                </div>
            
         
        {% endfor %}
        </div>
        {% if books.count == 0 %}
          <h1 class="text-center">No Books Contributed</h1>
        {% endif %}
         </div>
        </div>
    </section>
   
 
    <!-- Footer -->
    <!-- <section class="footer--section" >
      <div class="container-fluid text-center">
        <div class="footer--items row">
          <div class="footer--details col-lg-12">
            <p>© 2023 E-Library. All rights reserved.</p>
          </div>
        </div>
        </div>
      </section> -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
  </body>
</html>


editBook.html : This HTML template uses Bootstrap for styling, featuring a navigation bar and an “Add Book” section with a form posting to the ‘editBook’ URL. The form includes a CSRF token, and the template utilizes static files for custom styles. The footer includes a copyright notice, and Bootstrap’s JavaScript bundle ensures responsive behavior.

HTML




{% load static %}
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <link rel="stylesheet" href="{% static 'css/style.css' %}"/>
    <link rel="stylesheet" href="{% static 'css/addBook.css' %}"/>
</head>
  <body>
    <!-- Navbar -->
    <section class="navbar--section">
      <nav class="navbar navbar-expand-lg ">
        <div class="container-fluid">
          <a class="navbar-brand" href="#">E-Library</a>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse justify-content-end" id="navbarNav">
            <ul class="navbar-nav">
              <li class="nav-item">
                <a class="active nav-link " aria-current="page" href="/">Home</a>
              </li>
            </ul>
          </div>
        </div>
      </nav>
    </section>
 
    <!-- Add Book -->
    <section class="add--section">
        <form method="post" action="{% url 'editBook' book.id %}" enctype="multipart/form-data">
 
            {% csrf_token %}
            {{form}}
             
            <button type="submit" class="btn btn-primary mt-3">Add Book</button>
        </form>
    </section>
   
 
    <!-- Footer -->
    <section class="footer--section">
      <div class="container-fluid text-center">
        <div class="footer--items row">
          <div class="footer--details col-lg-12">
            <p>© 2023 E-Library. All rights reserved.</p>
          </div>
        </div>
 
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
  </body>
</html>


explore.html :This HTML template utilizes Bootstrap for styling, presenting a responsive navigation bar with links for ‘Home,’ ‘Explore,’ and user authentication. It displays books in categories (‘Education,’ ‘Fiction,’ ‘Science’) with concise details and buttons for viewing full details and accessing contributed books. Static files (‘style.css’) enhance custom styling, providing a user-friendly interface for an E-Library web page.

HTML




{% load static %}
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <link rel="stylesheet" href="{% static 'css/style.css' %}"/>
</head>
  <body>
    <!-- Navbar -->
    <section class="navbar--section">
      <nav class="navbar navbar-expand-lg ">
        <div class="container-fluid">
          <a class="navbar-brand" href="#">E-Library</a>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse justify-content-center" id="navbarNav">
            <ul class="navbar-nav">
              <li class="nav-item">
                <a class=" nav-link " aria-current="page" href="/">Home</a>
              </li>
              <li class="nav-item">
                <a class="nav-link active" href="/explore">Explore</a>
              </li>
              {% if user.is_authenticated %}
              <li class="nav-item">
                <a class="nav-link" href="logout">Logout</a>
              </li>
              {% else %}
              <li class="nav-item">
                <a class="nav-link" href="register">SignUp/Login</a>
              </li>
              {% endif %}
            </ul>
          </div>
        </div>
      </nav>
    </section>
<!--
    <section class="explore--section">
        <div class="input-group flex-nowrap">
        <span class="input-group-text" id="addon-wrapping">@</span>
        <input type="text" class="form-control" placeholder="Search by Name">
        </div>
    </section> -->
 
    <section class="explore--education--category m-5 ">
        <h2>Education</h2>
      <div class="container">
        <div class="row">
        {% for book in edu_books %}
 
                <div class="col-lg-4 m-3">
                 
                    <div class="card" style="height: 350px;">
                    <div class="card-body">
                        <h5 class="card-title text-center mb-3">{{book.title}}</h5>
                        <p class="card-text">Description : {{ book.summary|truncatechars:100 }}</p>
                        <p class="card-text">Pages : {{book.pages}}</p>
                        <p class="card-text">Category : {{book.category}}</p>
                        <p class="card-text">Contributed By : {{book.author}}</p>
                        <a href="{% url 'viewBook' book.id %}" class="btn btn-primary">Full Details</a>
                        <a href="{{book.pdf.url}}" class="btn btn-primary">View Book</a>
                    </div>
                    </div>
                 
                </div>
            
         
        {% endfor %}
      </div>
    </div>
    </section>
 
   <section class="explore--education--category m-5 ">
        <h2>Fiction</h2>
            <div class="container">
            <div class="row">
        {% for book in fiction_books %}
     
                <div class="col-lg-4 m-3">
                    <div class="card" style="height: 350px;">
                    <div class="card-body">
                        <h5 class="card-title text-center mb-3">{{book.title}}</h5>
                        <p class="card-text">Description : {{ book.summary|truncatechars:50 }}</p>
                        <p class="card-text">Pages : {{book.pages}}</p>
                        <p class="card-text">Category : {{book.category}}</p>
                        <p class="card-text">Contributed By : {{book.author}}</p>
 
                        <a href="{{book.pdf.url}}" class="btn btn-primary">View Book</a>
                    </div>
                    </div>
                </div>
            
         
        {% endfor %}
         </div>
        </div>
    </section>
 
    <section class="explore--education--category m-5">
        <h2>Science</h2>
        <div class="container">
            <div class="row">
        {% for book in science_books %}
         
                <div class="col-lg-4 m-3">
                  <a href="{% url 'viewBook' book.id %}">
                    <div class="card" style="height: 350px;">
                    <div class="card-body">
                        <h5 class="card-title text-center mb-3">{{book.title}}</h5>
                        <p class="card-text">Description : {{ book.summary|truncatechars:100 }}</p>
                        <p class="card-text">Pages : {{book.pages}}</p>
                        <p class="card-text">Category : {{book.category}}</p>
                        <p class="card-text">Contributed By : {{book.author}}</p>
 
                        <a href="{{book.pdf.url}}" class="btn btn-primary">View Book</a>
                    </div>
                    </div>
                  </a>
                </div
         
        {% endfor %}
         </div>
        </div>
    </section>
 
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
  </body>
</html>


home.html : This HTML template uses Bootstrap to design a responsive E-Library webpage with a navbar, brand section, features section, and a call-to-action for adding books. It includes modals for login prompts and adjusts buttons based on user authentication. The footer displays a copyright notice, and the styling is enhanced with a custom CSS file. The template aims for an attractive and user-friendly interface for exploring and contributing to the E-Library platform.

HTML




{% load static %}
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
          rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <link rel="stylesheet" href="{% static 'css/style.css' %}"/>
</head>
  <body>
    <!-- Navbar -->
    <section class="navbar--section">
      <nav class="navbar navbar-expand-lg ">
        <div class="container-fluid">
          <a class="navbar-brand" href="">E-Library</a>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
                  data-bs-target="#navbarNav" aria-controls="navbarNav"
                  aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse justify-content-center" id="navbarNav">
            <ul class="navbar-nav">
              <li class="nav-item">
                <a class="active nav-link " aria-current="page" href="/">Home</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" href="explore">Explore</a>
              </li>
              {% if user.is_authenticated %}
              <li class="nav-item">
                <a class="nav-link" href="{% url 'logout' %}">Logout</a>
              </li>
              <li>
                <a class="nav-link" href="{% url 'contri' user.id %}">Contributed</a>
              </li>
              {% else %}
              <li class="nav-item">
                <a class="nav-link" href="register">SignUp/Login</a>
              </li>
              {% endif %}
            </ul>
          </div>
        </div>
      </nav>
    </section>
 
    <!-- Brand -->
    <section class="brand--section ">
      <div class="container text-center">
        <div class="brand--items row">
          <div class="brand--image col-lg-6 col-md-12">
          </div>
          <div class=" col-lg-6 col-md-12">
            <p class="brand--details">The one stop solution for all your reading needs.</p>
            {% if user.is_authenticated %}
            <a class="btn btn-outline-success btn-lg" href="{% url 'addBook' user.id %}">Add Book</a>
            {% else %}
 
                      <!-- Button trigger modal -->
          <button type="button" class="btn btn-outline-success btn-lg" data-bs-toggle="modal"
                  data-bs-target="#staticBackdrop">
            Add Books
          </button>
 
          <!-- Modal -->
          <div class="modal fade" id="staticBackdrop" data-bs-backdrop="static"
               data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel"
               aria-hidden="true">
            <div class="modal-dialog">
              <div class="modal-content">
                <div class="modal-header">
                  <h1 class="modal-title fs-5" id="staticBackdropLabel">Dear User</h1>
                  <button type="button" class="btn-close" data-bs-dismiss="modal"
                          aria-label="Close"></button>
                </div>
                <div class="modal-body">
                Please login before adding a book
                </div>
                <div class="modal-footer">
                  <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                  <a type="button" class="btn btn-rimary" href="{% url 'login' %}">Login</a>
                </div>
              </div>
            </div>
          </div>
            {% endif %}
          </div>
        </div>
    </div>
    </section>
 
    <!-- Features -->
    <section class="feature--section">
      <div class="container text-center">
        <div class="feature--items row">
          <div class="feature--item col-lg-4 col-md-12">
            <div class="feature--icon">
              <img width="50" height="50"
                   src="https://img.icons8.com/ios-filled/50/book.png" alt="book"/>
            </div>
            <div class="feature--details">
              <h4>Books</h4>
            </div>
          </div>
          <div class="feature--item col-lg-4 col-md-12">
            <div class="feature--icon">
              <img width="64" height="64"
                   src="https://img.icons8.com/external-victoruler-solid-victoruler/64/external-read-education-and-school-victoruler-solid-victoruler.png" alt="external-read-education-and-school-victoruler-solid-victoruler"/>
            </div>
            <div class="feature--details">
              <h4>Read</h4>
            </div>
          </div>
          <div class="feature--item col-lg-4 col-md-12">
            <div class="feature--icon">
              <img width="64" height="64" src="https://img.icons8.com/pastel-glyph/64/download--v1.png"
                   alt="download--v1"/>
            </div>
            <div class="feature--details">
              <h4>Download</h4>
               
            </div>
          </div>
        </div>
      </div>
    </section>
 
    <!-- Add your book -->
    <section class="addBook--section">
      <div class="container-fluid text-center">
        <div class="addBook--items row">
          <div class="addBook--details col-lg-12">
            <h2>Add your book</h2>
            <p>Help us by contributing to the wider section of the books</p>
            {% if user.is_authenticated %}
            <a class="btn btn-outline-success btn-lg" href="{% url 'addBook' user.id %}">Add Book</a>
            {% else %}
 
                      <!-- Button trigger modal -->
          <button type="button" class="btn btn-outline-success" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
            Add Books
          </button>
 
          <!-- Modal -->
          <div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
            <div class="modal-dialog">
              <div class="modal-content">
                <div class="modal-header">
                  <h1 class="modal-title fs-5" id="staticBackdropLabel">Dear User</h1>
                  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                Please login before adding a book
                </div>
                <div class="modal-footer">
                  <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                  <a type="button" class="btn btn-rimary" href="{% url 'login' %}">Login</a>
                </div>
              </div>
            </div>
          </div>
            {% endif %}
          </div>
        </div>
    </section>
 
    <!-- Footer -->
    <section class="footer--section">
      <div class="container-fluid text-center">
        <div class="footer--items row">
          <div class="footer--details col-lg-12">
            <p>© 2023 E-Library. All rights reserved.</p>
          </div>
        </div>
 
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
  </body>
</html>


login.html : This Django template includes ‘register–header.html’ and ‘register–base.html’. The content showcases a login form with a clean two-column layout, featuring a jumbotron for emphasis and a card with email and password input. The design is visually appealing and encourages users to register if they don’t have an account.

HTML




{% include 'register--header.html' %}
 
    <h2 class="text-center mt-5">Login</h2>
    <form method="POST" action="{% url 'login' %}" class="register--form">
        {% csrf_token %}
          <!-- Section: Design Block -->
            <!-- Jumbotron -->
            <div class="px-4 py-5 px-md-5 text-center text-lg-start" style="background-color: hsl(0, 0%, 96%)">
              <div class="container">
                <div class="row gx-lg-5 align-items-center">
                  <div class="col-lg-6 mb-5 mb-lg-0">
                    <h1 class="my-5 display-3 fw-bold ls-tight">
                      The best place <br />
                      <span class="text-primary">for your reading needs</span>
                    </h1>
                    <!-- <p style="color: hsl(217, 10%, 50.8%)">
                      Lorem ipsum dolor sit amet consectetur adipisicing elit.
                      Eveniet, itaque accusantium odio, soluta, corrupti aliquam
                      quibusdam tempora at cupiditate quis eum maiores libero
                      veritatis? Dicta facilis sint aliquid ipsum atque?
                    </p> -->
                  </div>
 
                  <div class="col-lg-6 mb-5 mb-lg-0">
                    <div class="card">
                      <div class="card-body py-5 px-md-5">
                        <form>
                          <!-- 2 column grid layout with text inputs for the first and last names -->
                           
 
                          <!-- Email input -->
                          <div class="form-outline mb-4">
                            <input type="email" id="form3Example3" class="form-control" name="email"/>
                            <label class="form-label" for="form3Example3" >Email address</label>
                          </div>
 
                          <!-- Password input -->
                          <div class="form-outline mb-4">
                            <input type="password" id="form3Example4" class="form-control" name="password"/>
                            <label class="form-label" for="form3Example4">Password</label>
                          </div>
 
                          <!-- Submit button -->
                          <button type="submit" class="btn btn-primary btn-block mb-4">
                            Log In
                          </button>
                          <p>Don't  have an account? <a href="{% url 'register' %}">Register</a></p>
                          </div>
                        </form>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <!-- Jumbotron -->
 
<!-- Section: Design Block -->
        </form>
 
{% include 'register--base.html' %}


register–header.html : The HTML template sets up a webpage for authentication in an E-Library application. It includes Bootstrap for styling, and the `{% load static %}` tag is used to load static files. The body starts with a message section displaying any error messages in red text at the center of the page.

HTML




{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Authentication || E-Library</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
  <link rel="stylesheet" href="{% static 'css/register.css' %}">
</head>
<body>
  <div class="text-danger bg-body-tertiary text-center">
    {% for message in messages %}
      <h5>{{ message }}</h5>
    {% endfor %}
  </div>
</body>
</html>


register.html : The provided Django template is for a registration page in an E-Library application. It includes a header, a registration form with Bootstrap styling, and incorporates a two-column grid layout for the user’s first and last names. The form collects the user’s email and password, and it also provides a link to the login page for users who already have an account. The template follows a clean and modern design with a responsive layout.

HTML




{% include 'register--header.html' %}
 
    <h2 class="text-center mt-5">Register</h2>
    <form method="POST" action="{% url 'register' %}" class="register--form">
        {% csrf_token %}
          <!-- Section: Design Block -->
            <!-- Jumbotron -->
            <div class="px-4 py-5 px-md-5 text-center text-lg-start" style="background-color: hsl(0, 0%, 96%)">
              <div class="container">
                <div class="row gx-lg-5 align-items-center">
                  <div class="col-lg-6 mb-5 mb-lg-0">
                    <h1 class="my-5 display-3 fw-bold ls-tight">
                      The best place <br />
                      <span class="text-primary">for your reading needs</span>
                    </h1>
                    <!-- <p style="color: hsl(217, 10%, 50.8%)">
                      Lorem ipsum dolor sit amet consectetur adipisicing elit.
                      Eveniet, itaque accusantium odio, soluta, corrupti aliquam
                      quibusdam tempora at cupiditate quis eum maiores libero
                      veritatis? Dicta facilis sint aliquid ipsum atque?
                    </p> -->
                  </div>
 
                  <div class="col-lg-6 mb-5 mb-lg-0">
                    <div class="card">
                      <div class="card-body py-5 px-md-5">
                        <form>
                          <!-- 2 column grid layout with text inputs for the first and last names -->
                          <!-- First Name and Last Name -->
                          <div class="container">
                          <div class="row">
                          <div class="col-lg-6 form-outline mb-4">
                            <input type="text" id="form3Example3" class="form-control" name="first--name"/>
                            <label class="form-label" for="form3Example3" >First Name</label>
                          </div>
                           <div class="col-lg-6 form-outline mb-4">
                            <input type="text" id="form3Example3" class="form-control" name="last--name"/>
                            <label class="form-label" for="form3Example3" >Last Name</label>
                          </div>
                          </div>
                          </div>
 
 
 
                          <!-- Email input -->
                          <div class="form-outline mb-4">
                            <input type="email" id="form3Example3" class="form-control" name="email"/>
                            <label class="form-label" for="form3Example3" >Email address</label>
                          </div>
 
                          <!-- Password input -->
                          <div class="form-outline mb-4">
                            <input type="password" id="form3Example4" class="form-control" name="password"/>
                            <label class="form-label" for="form3Example4">Password</label>
                          </div>
 
                          <!-- Submit button -->
                          <button type="submit" class="btn btn-primary btn-block mb-4">
                            Sign up
                          </button>
                          <p>Already have an account? <a href="{% url 'login' %}">Login</a></p>
                          </div>
                           
                        </form>
                         
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <!-- Jumbotron -->
 
<!-- Section: Design Block -->
        </form>
 
{% include 'register--base.html' %}


viewBook.html :The provided HTML template is for a book details page in an E-Library application. It includes a navigation bar, displays book information such as title, category, author, pages, and provides a button to view the book. The template uses Bootstrap for styling, and it also checks if any books are contributed before displaying content. The commented-out section indicates a potential footer that is currently disabled.

HTML




{% load static %}
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <link rel="stylesheet" href="{% static 'css/style.css' %}"/>
    <link rel="stylesheet" href="{% static 'css/contri.css' %}"/>
    <style>
      *{
        box-sizing: border-box;
        margin: 0;
      }
    </style>
</head>
  <body>
    <!-- Navbar -->
    <section class="navbar--section">
      <nav class="navbar navbar-expand-lg ">
        <div class="container-fluid">
          <a class="navbar-brand" href="{% url 'explore' %}">Explore</a>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
        </div>
      </nav>
    </section>
 
    <!-- View Book -->
    <section class="contri--section">
      <div class="container">
            <div class="row">
                <div class="col-lg-12 mt-3">
                        <h3 class="text-center mb-3 h1">{{book.title}}</h3>
                        <div class="row">
                        <p class="col-lg-4 card-text text-center">Category : {{book.category}}</p>
                        <p class="col-lg-4 card-text text-center">Contributed By : {{book.author}}</p>
                        <p class="col-lg-4 card-text text-center">Pages : {{book.pages}}</p>
                        </div>
                        <a href="{{book.pdf.url}}" class="btn btn-primary">View Book</a>
                        <hr>
                        <p class="card-text h3">Description :</p>
                        <br>
                        <p >{{ book.summary | safe}}</p>
                </div>
            
         
        {% if books.count == 0 %}
          <h1 class="text-center">No Books Contributed</h1>
        {% endif %}
         </div>
        </div>
    </section
   
 
    <!-- Footer -->
    <!-- <section class="footer--section" >
      <div class="container-fluid text-center">
        <div class="footer--items row">
          <div class="footer--details col-lg-12">
            <p>© 2023 E-Library. All rights reserved.</p>
          </div>
        </div>
        </div>
      </section> -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
  </body>
</html>


Static Folder

addBook.css : The CSS code defines styles for a form section in an E-Library application. It sets padding, font weight, and a specific button style, ensuring a clean and centered layout for form elements with a distinctive button appearance.

CSS




.add--section{
    padding: 5% 7%;
    font-weight: 600;
}
.add--section form{
    display: flex;
    flex-direction: column;
    line-height: 2rem;
}
 
.btn{
    width: 30%;
    margin: 0 auto;
    padding: 0.5rem;
    background-color: #B1C381;
    color: #fff;
    border: none;
    font-weight: 600;
}


contri.css :The CSS code customizes button styles with a specific background color, removes borders, adjusts padding and font weight for a contribution section, and attempts to set an invalid width for cards.

CSS




.btn{
    background-color: #B1C381;
    border: none;
}
.contri--section{
    padding: 5% 7%;
    font-weight: 600;
}
 
.card{
    width: 2;
}


style.css : The CSS code customizes button styles with a specific background color, removes borders, adjusts padding and font weight for a contribution section, and attempts to set an invalid width for cards.

CSS




.navbar{
    background-color: #B1C381;
    font-weight: 600;
}
.nav-link{
    margin: 0 1rem;
}
.navbar-brand{
    font-size: 2rem;
}
 
/* Brand */
.brand--section{
    padding:5% 7%;
    color: #B1C381;
    font-weight: 600;
}
.brand--details{
    padding: 3% 7%;
    color: #B1C381;
    font-weight: 600;
    font-size: 3rem;
}
 
/* Features */
.feature--section{
    padding: 5% 7%;
    background-color: #B1C381;
    font-weight: 600;
}
.feature--icon{
    padding: 2rem;
}
 
/* Add your Book */
.addBook--section{
    padding: 5% 7%;
    color: #B1C381;
    font-weight: 600;
}
 
/* Footer */
.footer--section{
    padding: 5% 7%;
    background-color: #B1C381;
    font-weight: 600;
}
 
/* Explore */
 
.explore--section{
    padding: 3% 5%;
    color: #B1C381;
    font-weight: 600;
}
 
.explore--section input{
    color:#B1C381;
}
 
/* Register */


admin.py:Here we are registering our models.

Python3




from django.contrib import admin
from .models import EBooksModel
# Register your models here.
 
admin.site.register(EBooksModel)


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

Conclusion

The E-book Library developed using Django provides a user-friendly platform for exploring, contributing, and managing a diverse collection of e-books. The web application incorporates a responsive design with a cohesive color scheme, ensuring an aesthetically pleasing and intuitive user experience. Features include user authentication, book exploration by category, book details viewing, and user contribution functionality. The application encourages user engagement by allowing contributions, ensuring a dynamic and growing library. With a robust backend powered by Django, the E-book Library effectively manages data, providing a secure and efficient environment for book enthusiasts.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads