Skip to content

Django book catalog

Django book catalog app. Follow these steps to set it up:

Requrements: - Python3 installed

1. Install Django and Set Up Your Project

Ensure you have Django installed. You can install it using pip:

pip install django

Create a new Django project:

django-admin startproject bookcatalog .

Create a Django app within your project:

python manage.py startapp books

Now we have two directories: - bookcatalog - project directory - books - app directory - manage.py - management utility

2. Set Up Your Django App

bookcatalog/settings.py

Add the books app to your INSTALLED_APPS in settings.py and configure your database (SQLite):

INSTALLED_APPS = [
    ...,
    'books',
]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

books/models.py

Define your Book model:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=200)
    description = models.TextField()
    published_date = models.DateField()

    def __str__(self):
        return self.title

books/admin.py

Register the Book model:

from django.contrib import admin
from .models import Book

admin.site.register(Book)

books/urls.py

Create books/urls.py for your app's URLs:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.book_list, name='book_list'),
    path('book/<int:id>/', views.book_detail, name='book_detail'),
    path('book/edit/<int:id>/', views.book_edit, name='book_edit'),
    path('book/new/', views.book_create, name='book_create'),
    path('login/', views.user_login, name='login'),
    path('logout/', views.user_logout, name='logout'),
]

bookcatalog/urls.py

Include the books URLs in your project's urls.py:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('books.urls')),
]

books/forms.py

Create a form for your Book model:

from django import forms
from .models import Book

class BookForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ['title', 'author', 'description', 'published_date']

books/views.py

Create views for listing books, viewing details, editing books, and handling logins:

from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from .models import Book
from .forms import BookForm
def book_list(request):
   books = Book.objects.all()
   return render(request, 'books/book_list.html', {'books': books})
def book_detail(request, id):
   book = get_object_or_404(Book, id=id)
   return render(request, 'books/book_detail.html', {'book': book})
@login_required
def book_edit(request, id):
   book = get_object_or_404(Book, id=id)
   if request.method == 'POST':
       form = BookForm(request.POST, instance=book)
       if form.is_valid():
           form.save()
           return redirect('book_detail', id=book.id)
   else:
       form = BookForm(instance=book)
   return render(request, 'books/book_edit.html', {'form': form})
def user_login(request):
   if request.method == 'POST':
       username = request.POST['username']
       password = request.POST['password']
       user = authenticate(request, username=username, password=password)
       if user is not None:
           login(request, user)
           return redirect('book_list')
       else:
           return HttpResponse("Invalid login details")
   return render(request, 'books/login.html')
def user_logout(request):
   logout(request)
   return redirect('login')

3. Templates

books/templates/books/book_list.html

Create the template for listing books:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Book List</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
    <style>
        body { font-family: Arial, sans-serif; }
        table { width: 100%; border-collapse: collapse; }
        td, th { padding: 8px; border: 1px solid #ccc; }
        th { background-color: #f4f4f4; }
        a { text-decoration: none; color: #0366d6; }
    </style>
</head>
<body>
    <h1>Books</h1>
    <table>
        <tr>
            <th>Title</th>
            <th>Author</th>
            <th></th>
        </tr>
        {% for book in books %}
        <tr>
            <td>{{ book.title }}</td>
            <td>{{ book.author }}</td>
            <td><a href="{% url 'book_detail' book.id %}">View</a></td>
        </tr>
        {% endfor %}
    </table>
    {% if user.is_authenticated %}
    <p><a href="{% url 'book_create' %}">Add New Book</a></p>
    <p><a href="{% url 'logout' %}">Logout</a></p>
    {% else %}
    <p><a href="{% url 'login' %}">Login</a></p>
    {% endif %}
</body>
</html>

books/templates/books/book_detail.html

Create the template for book details:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ book.title }}</title>
    <style>
        body { font-family: Arial, sans-serif; }
        a { text-decoration: none; color: #0366d6; }
    </style>
</head>
<body>
    <h1>{{ book.title }}</h1>
    <p><strong>Author:</strong> {{ book.author }}</p>
    <p><strong>Description:</strong> {{ book.description }}</p>
    <p><strong>Published Date:</strong> {{ book.published_date }}</p>
    {% if user.is_authenticated %}
    <p><a href="{% url 'book_edit' book.id %}">Edit</a></p>
    <p><a href="{% url 'book_list' %}">Back to list</a></p>
    {% endif %}
</body>
</html>

books/templates/books/book_edit.html

Create the template for editing books:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Edit Book</title>
   <style>
body { font-family: Arial, sans-serif; }
       form { max-width: 500px; margin: 0 auto; }
       label { display: block; margin-top: 10px; }
       input, textarea { width: 100%; padding: 8px; margin-top: 4px; }
       button { padding: 10px 20px; margin-top: 20px; }
   </style>
</head>
<body>
   <h1>Edit Book</h1>
   <form method="post">
       {% csrf_token %}
       {{ form.as_p }}
       <button type="submit">Save</button>
   </form>
</body>
</html>

books/templates/books/login.html

Create the template for the login form:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <style>
        body { font-family: Arial, sans-serif; }
        form { max-width: 300px; margin: 0 auto; }
        label { display: block; margin-top: 10px; }
        input { width: 100%; padding: 8px; margin-top: 4px; }
        button { padding: 10px 20px; margin-top: 20px; }
    </style>
</head>
<body>
    <h1>Login</h1>
    <form method="post">
        {% csrf_token %}
        <label for="username">Username</label>
        <input type="text" name="username" required>
        <label for="password">Password</label>
        <input type="password" name="password" required>
        <button type="submit">Login</button>
    </form>
</body>
</html>

books/views.py:

from django.contrib.auth.decorators import login_required

@login_required
def book_create(request):
    if request.method == 'POST':
        form = BookForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('book_list')
    else:
        form = BookForm()
    return render(request, 'books/book_create.html', {'form': form})

books/teamplates/books/book_create.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Add New Book</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
    <style>
        body { font-family: Arial, sans-serif; }
        form { max-width: 400px; margin: 0 auto; }
        div { margin-bottom: 10px; }
        label { display: block; margin-bottom: 5px; }
        input[type="text"], textarea { width: 100%; padding: 8px; border: 1px solid #ccc; }
        input[type="submit"] { padding: 8px 16px; border: none; background-color: #28a745; color: white; cursor: pointer; }
    </style>
</head>
<body>
    <h1>Add New Book</h1>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <div>
            <input type="submit" value="Add Book">
        </div>
    </form>
    <p><a href="{% url 'book_list' %}">Back to book list</a></p>
</body>
</html>

4. Apply Migrations and Create Superuser for Admin Access

Apply the migrations to create the necessary database tables. To create and manage users directly, create a superuser:

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser

5. Run Server

Run your development server:

python manage.py runserver

Open the browser and navigate to http://127.0.0.1:8000/ to see your app in action. You can list, view, and edit books, and login as a user to access edit features.