Build a Book Collection REST API

Build a full CRUD REST API for a book collection using Django and DRF.

Introduction

30 Second Summary

Every app you use daily, from your music library to your online shopping cart, stores and retrieves data through APIs. These invisible connections are the backbone of modern software.

In this project, you will build a fully functional REST API that manages a book collection using Django and Django REST Framework.

What You'll Build

You'll open your browser, see your entire book collection rendered as JSON, add new books through a web form, and delete entries with a single click.

By the end of this project, you'll have:

  • A running REST API where you can create, browse, update, and delete books through proper endpoints that you test directly in your browser.
  • A browsable web interface built into Django REST Framework where you submit forms, see JSON responses, and interact with your API visually without needing any external tools.
  • Automatic input validation that rejects bad data (like negative page counts) and returns clear error messages to the caller.
  • Secret Mission: Add search and ordering so users can find books by title or author and sort results by any field.

Are there any prerequisites?

You should be comfortable with basic Python concepts like variables, functions, and classes. No prior experience with Django or APIs is needed.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters.

You're going to build a Book Collection REST API from scratch using Django and Django REST Framework. This is the exact pattern used in production Django applications, and the foundation interviewers expect to see from a backend developer candidate.

Set Up Your Django Project

Every Django API starts with a properly configured project. Before you can build any endpoints, you need Django and Django REST Framework installed in an isolated environment.

In this step, you'll create a virtual environment, install your dependencies, scaffold a Django project, and confirm everything works by visiting the famous Django rocket page in your browser.

In this step, get ready to:
  • Create a virtual environment and install Django and DRF.
  • Create a new Django project and a books app.
  • Configure settings and run the development server.
Create a virtual environment and install dependencies

A virtual environment keeps your project's packages separate from your system Python. This prevents version conflicts between projects.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Visual Studio Code and press Enter to open it.
  • Open the integrated terminal by pressing Ctrl+` (both macOS and Windows).
  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your virtual environment by running this command:

macOS

python3 -m venv bookapi-env

Windows

py -m venv bookapi-env
  • Activate the virtual environment by running:

macOS

source bookapi-env/bin/activate

Windows

bookapi-env\Scripts\activate

Your terminal prompt now shows (bookapi-env) at the beginning. This confirms you're working inside the virtual environment.

Don't see (bookapi-env) in your prompt?

On Windows, if you see an error about execution policies, run Set-ExecutionPolicy -Scope CurrentUser RemoteSigned first, then try the activate command again.

On macOS, make sure you used source before the path. Without it, the command won't activate the environment.

help me activate my Python virtual environment

  • Install Django and Django REST Framework by running:
pip install Django==6.0.7 djangorestframework==3.17.1

What does this command do?

pip install downloads and installs Python packages. The == pins exact versions so every learner gets the same setup.

Django is the web framework that handles routing, databases, and project structure. djangorestframework adds the tools you need to build REST APIs on top of Django.

  • Confirm Django installed correctly by running:
python -m django --version

You should see 6.0.7 printed in your terminal.

Seeing a different version or an error?

If you see a "No module named django" error, make sure your virtual environment is activated. You should see (bookapi-env) in your terminal prompt.

If you see a different version number, re-run the install command with the exact version pin: pip install Django==6.0.7.

help me verify my Django installation

Create the Django project and books app

Django organizes code into "projects" (the overall container) and "apps" (modules that handle a specific feature). Your project will be called bookapi and you'll create a books app inside it to hold all the book-related logic.

  • Scaffold your Django project and books app by running these commands:
django-admin startproject bookapi
cd bookapi
python manage.py startapp books

What do these commands do?

  • django-admin startproject bookapi creates a new folder called bookapi/ with Django's core configuration files inside.
  • cd bookapi moves you into the new project folder so all future commands run from the right place.
  • python manage.py startapp books creates a books/ folder with model, view, and config files ready for your book collection logic.
  • Confirm your project structure by running:
ls

You should see bookapi, books, and manage.py in the output.

Missing files or folders?

If you only see manage.py and bookapi/ but not books/, make sure you ran python manage.py startapp books from inside the bookapi folder (the one containing manage.py).

help me fix my Django project structure

Configure settings and run the development server

Django doesn't know about your new books app or DRF until you register them in the project settings. You need to tell Django to include both packages.

  • In VS Code, click File in the top menu bar.
  • Click Open Folder.
  • Navigate to your Desktop and select the bookapi folder, then click Open.
  • In the Explorer sidebar, expand bookapi/ and click settings.py to open it.
  • Find the INSTALLED_APPS list. It looks like this:
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
  • Add 'rest_framework' and 'books' as the last two entries in the list, so it looks like this:
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'books',
]

What do these entries do?

'rest_framework' activates DRF so you can use serializers, viewsets, and the browsable API interface later.

'books' registers your new app so Django includes its models and views when running the project.

  • Save settings.py by pressing Cmd+S (macOS) or Ctrl+S (Windows).

Before you run the server, what do you think you'll see when you visit the URL in your browser? Will it be an error, a blank page, or something else?

  • Open your terminal in VS Code by pressing Ctrl+` and start the development server by running:
python manage.py runserver

What does this command do?

manage.py runserver starts a local web server on your machine at http://127.0.0.1:8000/. It keeps running in your terminal until you stop it with Ctrl+C.

  • Open your web browser and visit http://127.0.0.1:8000/.

You should see the Django "Congratulations!" page with a rocket animation. This confirms Django is installed correctly and your project is running.

Don't see the rocket page?

If you see "ModuleNotFoundError: No module named 'rest_framework'", your virtual environment might not be activated in the terminal. Check for (bookapi-env) in your prompt. If it's missing, activate it again and re-run the server.

If the page won't load, make sure the server is still running in your terminal. You should see output ending with a line mentioning http://127.0.0.1:8000/.

help me get the Django development server running

✔️ Awesome, I've got everything!

Great. Double check that you've saved settings.py and your server is still running in the terminal.

ⓧ I'd like to double check the full code

The only file you edited manually is settings.py. Scroll up and confirm your INSTALLED_APPS list matches the "after" code block above. It should end with:

    'rest_framework',
    'books',
]

All other files (manage.py, wsgi.py, apps.py) were auto-generated by Django and should not be modified.

Your Django project is up and running. Next up, you'll define the Book model that tells Django what a "book" looks like in your database.

Define Your Book Model and Database

Your Django project is running, but there's no data for the API to serve yet. You need a database table that defines what a "book" looks like before you can create, read, update, or delete books through the API.

In this step, you'll define a Book model that maps to a database table, run migrations to build that table, and register the model in Django's admin panel so you can manually add your first book.

In this step, get ready to:
  • Define the Book model with fields for title, author, ISBN, page count, language, and creation date.
  • Create and run database migrations.
  • Register the model in Django admin and add your first book.
Define the Book model

A model in Django is a Python class that describes a database table. Each attribute on the class becomes a column in the table.

  • In VS Code, open the file books/models.py inside your bookapi project folder.
  • Replace the contents of the file with the following code:
from django.db import models

class Book(models.Model):
    # The book's title, limited to 200 characters
    title = models.CharField(max_length=200)
    # The author's name
    author = models.CharField(max_length=200)
    # ISBN is optional (blank=True) and defaults to empty
    isbn = models.CharField(max_length=13, blank=True, default='')
    # Number of pages, must be zero or positive
    page_count = models.PositiveIntegerField(default=0)
    # Language defaults to English
    language = models.CharField(max_length=50, default='English')
    # Automatically set when the book is first created
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.title} by {self.author}"

What does this code do?

  • Each field (CharField, PositiveIntegerField, DateTimeField) maps to a database column type. Django handles the SQL for you.
  • Fields with blank=True and default='' are optional. The learner can skip them when creating a book.
  • The __str__ method controls how a book appears in the admin panel and shell. Without it, you'd see unhelpful labels like "Book object (1)".
  • Save books/models.py.
Create and run migrations

Django doesn't update the database automatically when you change a model. You need to generate a migration file that describes the change, then apply it.

  • Switch back to your terminal. If the development server is still running, press Ctrl+C to stop it.
  • Generate the migration file by running this command:
python manage.py makemigrations

You should see output confirming Django detected your new model:

Migrations for 'books':
  books/migrations/0001_initial.py
    + Create model Book

What is a migration?

A migration is a file that records changes to your models. Django reads these files to figure out what SQL to run against your database. This means you never write raw SQL to create tables.

Seeing "No changes detected"?

  • Make sure you saved books/models.py before running the command.
  • Confirm that 'books' is listed in INSTALLED_APPS in bookapi/settings.py. Django only detects models from registered apps.

Help me troubleshoot why Django isn't detecting my Book model changes.

  • Apply the migration to create the actual database table by running:
python manage.py migrate

You should see several lines ending with OK, including Applying books.0001_initial... OK.

Why so many migrations?

Django ships with built-in apps (admin, auth, sessions) that also need database tables. The first time you run migrate, it creates tables for all of them plus your Book table.

Register the model in Django admin and create a superuser

Django includes a built-in admin interface that gives you a visual way to manage your data. You need to register your Book model so it appears in the admin panel.

  • In VS Code, open books/admin.py and replace its contents with the following code:
from django.contrib import admin
from .models import Book

# Register Book so it appears in the admin panel
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    # Columns visible in the admin list view
    list_display = ['title', 'author', 'isbn', 'page_count', 'language', 'created_at']
    # Fields searchable from the admin search bar
    search_fields = ['title', 'author']

What does this code do?

  • The @admin.register(Book) decorator tells Django to show the Book model in the admin interface.
  • The list_display setting controls which columns appear on the book list page.
  • The search_fields setting adds a search bar that filters books by title or author.
  • Save books/admin.py.

To log into the admin panel, you need a superuser account. This command will prompt you for a username, email, and password.

  • Create a superuser account by running this command:
python manage.py createsuperuser

What will this command ask?

  • Username: enter any name you like (e.g. admin).
  • Email address: enter any email (e.g. admin@example.com).
  • Password: type a password (it won't be displayed as you type). You'll be asked to confirm it a second time.

After entering all fields, you'll see Superuser created successfully. in the terminal.

Password too short or too common?

Django may warn that your password is too short or too common. For this local project, you can type y to bypass the warning and use your simple password anyway.

Help me resolve a Django createsuperuser password validation issue.

  • Start the development server again by running:
python manage.py runserver

Before you open the admin, what do you expect to see when you navigate to http://127.0.0.1:8000/admin/?

  • Open your browser and visit http://127.0.0.1:8000/admin/.
  • Log in with the username and password you just created.
  • Click Books in the left sidebar.
  • Click Add Book in the top right.
  • Fill in the form with any book details (e.g. title: The Pragmatic Programmer, author: David Thomas).
  • Click Save.

You should see your book listed in the admin table with all the columns you configured in list_display.

Don't see Books in the admin?

  • Make sure you saved books/admin.py after pasting the code.
  • Verify the import line reads from .models import Book (note the dot before models).
  • Restart the dev server (Ctrl+C, then python manage.py runserver again) and refresh the admin page.

Help me figure out why my Book model isn't showing up in the Django admin.

✔️ Awesome, I've got everything!

Great. Double check you've saved both books/models.py and books/admin.py.

ⓧ I'd like to double check the full code

Here is the complete books/models.py:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=200)
    isbn = models.CharField(max_length=13, blank=True, default='')
    page_count = models.PositiveIntegerField(default=0)
    language = models.CharField(max_length=50, default='English')
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.title} by {self.author}"

Here is the complete books/admin.py:

from django.contrib import admin
from .models import Book

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ['title', 'author', 'isbn', 'page_count', 'language', 'created_at']
    search_fields = ['title', 'author']

Your database is ready and you've confirmed data exists by adding a book through the admin. Next up, you'll expose this data as a proper REST API endpoint that returns JSON.

Create Your First API Endpoint

You have a Book model in the database and you can manage records through the admin panel. That's great for administrators, but real applications expose data through APIs that other programs and frontends can consume.

Right now, your book data is locked behind the admin interface. In this step, you'll build a proper REST endpoint that serves your book data as JSON, giving you your first visible API response in the browser.

In this step, get ready to:
  • Create a serializer to convert Book model instances to JSON.
  • Create a viewset to handle API requests for books.
  • Wire up URL routing to expose the endpoint at /api/books/.
Create a BookSerializer

A serializer translates between Django model instances and JSON. It defines which fields to include in the API response and how to validate incoming data.

  • In VS Code, create a new file called serializers.py inside your books folder (the same folder that contains models.py).
  • Add the following code to books/serializers.py:
from rest_framework import serializers
from .models import Book


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'isbn', 'page_count', 'language', 'created_at']
        read_only_fields = ['id', 'created_at']

    def validate_page_count(self, value):
        if value < 0:
            raise serializers.ValidationError("Page count cannot be negative.")
        return value

What does this code do?

  • ModelSerializer automatically generates serializer fields based on your Book model, saving you from defining each field manually.
  • fields lists exactly which model fields appear in the JSON response.
  • read_only_fields prevents id and created_at from being set by API consumers. The database handles these automatically.
  • validate_page_count is a field-level validator that rejects negative page counts with a clear error message instead of a database-level crash.
  • Save books/serializers.py.
Create a BookViewSet

A viewset groups the logic for handling API requests (listing, retrieving, creating, etc.) into a single class. It decides what data to serve and which serializer to use.

  • Open books/views.py in VS Code.
  • Replace the entire contents of the file with the following code:
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer


class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all().order_by('-created_at')
    serializer_class = BookSerializer

What does this code do?

  • ModelViewSet provides built-in actions for listing, retrieving, creating, updating, and deleting objects.
  • queryset tells the viewset which database records to serve. The order_by('-created_at') sorts books newest-first.
  • serializer_class points to the BookSerializer you just created, which controls the JSON shape.
  • Save books/views.py.
  • Switch to the terminal where your dev server is running. Because you added a new file (serializers.py), Django's auto-reloader may not detect the change.
  • Stop the server with Ctrl+C, then restart it by running:
python manage.py runserver
  • Confirm the server starts without any errors in the terminal output. You should see the line starting with Starting development server at http://127.0.0.1:8000/.

Seeing an ImportError or ModuleNotFoundError?

  • Check that serializers.py is inside the books/ folder, not at the project root.
  • Make sure the import in views.py says from .serializers import BookSerializer with a leading dot.
  • Verify you saved both files before restarting the server.

Help me fix an import error in my Django views.py file.

Wire up a DefaultRouter in your URL configuration

Your viewset is ready but has no URL attached to it. A router automatically generates URL patterns for your viewset, mapping HTTP methods to the correct actions.

  • Open bookapi/urls.py in VS Code (this is in the inner bookapi folder, next to settings.py).
  • Replace the entire contents of the file with the following code:
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from books.views import BookViewSet

router = DefaultRouter()
router.register(r'books', BookViewSet)

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

What does this code do?

  • DefaultRouter automatically creates URL patterns for list, detail, create, update, and delete operations. It also generates an API root page at /api/ that lists all available endpoints.
  • router.register(r'books', BookViewSet) tells the router to serve the BookViewSet at the /api/books/ URL prefix.
  • include(router.urls) merges the generated URL patterns into Django's main URL configuration under the api/ path.

Why DefaultRouter instead of manually writing URL patterns?

You could write each URL pattern by hand, but DefaultRouter eliminates boilerplate by generating them from your viewset. It also creates a browsable API root page that lists all your endpoints as clickable links.

This is the standard pattern used in production Django APIs because it keeps your URL configuration consistent as you add more viewsets.

  • Save bookapi/urls.py.

Before you visit the endpoint, what do you think you'll see at http://127.0.0.1:8000/api/books/? Will it show plain JSON, an error, or something else?

  • Open your browser and visit http://127.0.0.1:8000/api/books/.

You should see the DRF browsable API page with a styled interface showing your book data as JSON. The book you added through the admin panel earlier appears in the results list.

Seeing a Page not found (404) error?

  • Make sure the URL is exactly http://127.0.0.1:8000/api/books/ with the trailing slash.
  • Check that bookapi/urls.py has path('api/', include(router.urls)) and not a typo in the prefix.
  • If you just saved the file, the dev server should auto-reload. If it did not, stop it with Ctrl+C and restart with python manage.py runserver.

Help me fix a 404 error on my DRF API endpoint.

Try the API root too

Visit http://127.0.0.1:8000/api/ to see the API root page that DefaultRouter generates automatically. It lists all available endpoints as clickable links.

✔️ Awesome, I've got everything!

Great. Make sure all three files are saved: books/serializers.py, books/views.py, and bookapi/urls.py.

ⓧ I'd like to double check the full code

Here are the three files you created or modified in this step.

from rest_framework import serializers
from .models import Book


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'isbn', 'page_count', 'language', 'created_at']
        read_only_fields = ['id', 'created_at']

    def validate_page_count(self, value):
        if value < 0:
            raise serializers.ValidationError("Page count cannot be negative.")
        return value
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer


class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all().order_by('-created_at')
    serializer_class = BookSerializer
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from books.views import BookViewSet

router = DefaultRouter()
router.register(r'books', BookViewSet)

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

Your first API endpoint is live. Next up, you'll put this endpoint to the test by trying to create, update, and delete books directly from the browsable API.

Enable Full CRUD Operations

Your API can serve book data, but a real application needs to create, update, and delete resources too. These operations are collectively called CRUD (Create, Read, Update, Delete).

Your ModelViewSet already unlocks all of these operations out of the box. In this step, you'll test every CRUD operation through the browsable API and see how your serializer validation protects the database from bad data.

In this step, get ready to:
  • Create a new book by POSTing data through the browsable API.
  • Test field-level validation by submitting invalid data.
  • Update and delete a book through the detail endpoint.
Understand what ModelViewSet provides

A ModelViewSet is the most powerful viewset DRF offers. It automatically provides six actions for your model without writing any extra code.

  • In VS Code, open books/views.py to see your current viewset.
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer


class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all().order_by('-created_at')
    serializer_class = BookSerializer

What does ModelViewSet give you?

ModelViewSet provides .list(), .retrieve(), .create(), .update(), .partial_update(), and .destroy() actions. That means your API supports GET, POST, PUT, PATCH, and DELETE requests with zero extra configuration.

Compare this to a ReadOnlyModelViewSet, which only provides .list() and .retrieve(). ModelViewSet is the go-to choice when you want full CRUD on a resource.

Let's prove these write operations work by creating a brand new book through the browsable API.

Create a book through the browsable API

DRF's browsable API gives you an HTML form at the bottom of every list endpoint. You can use it to POST new resources directly from your browser.

  • Make sure your development server is running. If it stopped, start it again by running:
python manage.py runserver
  • In your browser, visit http://127.0.0.1:8000/api/books/.
  • Scroll to the bottom of the page. You'll see an HTML form with fields for each book attribute.
  • Fill in the form with these values:
  • Title: The Pragmatic Programmer
  • Author: David Thomas
  • Isbn: 9780135957059
  • Page count: 352
  • Language: English
  • Click the **POST** button.

The page refreshes and shows your newly created book as JSON, including an auto-generated id and created_at timestamp. The response status shows HTTP 201 Created at the top of the page.

Not seeing the form at the bottom?

Make sure you're visiting the URL with a trailing slash: http://127.0.0.1:8000/api/books/. Without the slash, Django may redirect and the form won't appear.

Also confirm rest_framework is in your INSTALLED_APPS in settings.py. The browsable API needs this to render its templates.

Help me debug the browsable API form not appearing.

Test validation with invalid data

Your serializer includes a validate_page_count method that rejects negative values. The model also requires a title (it's a CharField with no blank=True). Let's see what happens when you break these rules.

  • Scroll back to the form at the bottom of the books list page.
  • Leave the Title field empty.
  • Enter -5 in the Page count field.
  • Enter Test Author in the Author field.
  • Click **POST**.

Before you check the result, predict what you think the API will do. Will the book be created, or will you get an error?

The response shows HTTP 400 Bad Request with clear error messages explaining exactly which fields failed validation and why.

Where do these validation errors come from?

DRF applies validation at two layers. First, the serializer checks field constraints (like title being required because the model's CharField doesn't allow blanks). Second, your custom validate_page_count method runs and catches negative numbers.

This gives API consumers a clear 400 response with actionable messages, instead of a confusing 500 server error from the database.

Update and delete a book

Individual book records live at their own detail URL. You'll use this URL to update a book's title and then delete it entirely.

  • In the book list at http://127.0.0.1:8000/api/books/, find the book you created earlier (The Pragmatic Programmer).
  • Click its url link in the JSON response to navigate to its detail page (it looks like http://127.0.0.1:8000/api/books/2/).

The detail page shows a single book's data and provides a form for updating it. It also has a DELETE button in the top right.

  • In the form at the bottom, change the Title field to The Pragmatic Programmer (20th Anniversary Edition).
  • Click **PUT** to submit the update.

The page refreshes and shows the updated title in the JSON response. The status reads HTTP 200 OK.

Now try deleting the book.

  • Click the red **DELETE** button in the top right corner of the detail page.
  • Confirm the deletion when prompted.

The response shows HTTP 204 No Content. The book is gone from your database.

  • Navigate back to http://127.0.0.1:8000/api/books/ to confirm the deleted book no longer appears in the list.

What are PUT vs PATCH?

PUT replaces the entire resource. You must send all fields, even the ones you didn't change. PATCH updates only the fields you send. Both are available on your detail endpoint.

Getting a 404 on the detail page?

Make sure the ID in your URL matches a book that actually exists. If you already deleted it, the URL won't resolve. Go back to the list view and pick a different book's URL.

Help me troubleshoot a 404 on my book detail endpoint.

✔️ Awesome, I've got everything!

Great. Your API handles full CRUD and rejects invalid data with clear error messages.

ⓧ I'd like to double check the full code

Here's your books/views.py:

from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer


class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all().order_by('-created_at')
    serializer_class = BookSerializer

And your books/serializers.py:

from rest_framework import serializers
from .models import Book


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'isbn',
                  'page_count', 'language', 'created_at']
        read_only_fields = ['id', 'created_at']

    def validate_page_count(self, value):
        if value < 0:
            raise serializers.ValidationError(
                "Page count cannot be negative.")
        return value

You now have a fully functional REST API that handles creating, reading, updating, and deleting books. Your serializer validates incoming data and returns clear error messages when something's wrong. Next up, you'll extend this API with search and ordering in the Secret Mission.

Secret mission

Add Search and Ordering

Your API works great for a small collection, but what happens when you have hundreds of books? In this secret mission, add search and ordering so users can find books by title or author and sort results by any field.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely locally, so there are no ongoing costs.

Resources you used:

  • The bookapi project folder on your Desktop (contains all project code and the SQLite database).
  • The Python virtual environment folder on your Desktop.
  • The Django development server (running process in your terminal).

Keep everything running

No action needed. Choose this if you're still actively building or want to keep experimenting with your API.

  • Your Django development server stays running at http://127.0.0.1:8000/.
  • Your virtual environment stays activated in your terminal session.
  • All project files remain on your Desktop.

Pause - I'll come back to this later

Shut down running processes to free up memory. Your files stay on disk so you can pick up where you left off.

  • In the terminal where the server is running, press Ctrl+C to stop the Django development server.
  • Deactivate your virtual environment by running:
deactivate

When you come back, navigate to your project folder, reactivate the virtual environment, and start the server again.

Delete - I don't want to use this again

Remove all project resources and start fresh. This deletes your code, database, and virtual environment permanently.

  • In the terminal where the server is running, press Ctrl+C to stop the Django development server.
  • Deactivate your virtual environment by running:
deactivate
  • Navigate to your Desktop and delete the project folder and virtual environment by running:

macOS

cd ~/Desktop
rm -rf bookapi
rm -rf venv

Windows

cd ~\Desktop
rmdir /s /q bookapi
rmdir /s /q venv
  • Confirm the folders are gone by running:
ls

You should no longer see bookapi or venv in the output.

Nice Work!

Nice Work!

Nice work! You just built a fully functional Book Collection REST API using Django and Django REST Framework. You can create, browse, update, and delete books through a proper set of REST endpoints, all accessible through a browsable web interface.

You've learned how to:

  • Built a complete Django project from scratch with a Book model, database migrations, and an admin interface for managing data.
  • Created a REST API using DRF serializers, viewsets, and routers that serves JSON through a browsable web interface.
  • Implemented full CRUD operations (Create, Read, Update, Delete) with input validation that rejects invalid data with clear error messages.
  • Added search and ordering capabilities using DRF filter backends so users can find and sort books instantly (Secret Mission).

Ready to quiz yourself?