This guide walks you through setting up a local Django backend for a simple hackathon project (in this case, it's a notes app). You'll learn how to install Python and Django on Windows/Mac/Linux, create a Django project and app, configure the built-in SQLite database, and use the Django REST Framework (DRF) to build a basic CRUD API.
- What is Django? Django is "a high-level Python web framework that encourages rapid development and clean, pragmatic design". It lets you build web applications quickly, handling many common tasks (like database access and routing) for you.
- What is Django REST Framework? DRF is "a powerful and flexible toolkit for building Web APIs". It makes it easy to expose your data (e.g. notes) as JSON over HTTP so that any frontend (mobile app, web UI, etc.) can use it.
- Local deployment: All steps below target running Django on your own machine. We'll use SQLite (the default database), which requires no extra installation. No cloud or complex servers are needed.
- Django Backend HackPack
-
Install Python (3.8+).
- Windows: Download from python.org. Run the installer and check "Add Python to PATH".
- macOS: Python 3 is often pre-installed. If not, use Homebrew (
brew install python3) or download from python.org. - Linux (Ubuntu/Debian): Use your package manager. For example:
sudo apt update sudo apt install python3 python3-pip
-
Verify installation by running
python3 --versionandpip3 --version(should show Python 3.x).
Tip
You should see something like Python 3.11.4 and pip 23.1.2. The exact numbers may differ, but as long as Python is 3.8+, you're good!
-
Create a virtual environment. This keeps project dependencies isolated, so packages you install for this project won't conflict with other Python projects on your machine. From your project folder, run:
python3 -m venv venv # Activate it: # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate
Important
After activation, you should see (venv) at the beginning of your terminal prompt. This confirms you're working inside the virtual environment.
-
Install Django and DRF. With Python ready, install the required packages via
pip:pip install django djangorestframework
Tip
Run pip list to verify. You should see Django and djangorestframework in the list of installed packages.
In Django, a project is your entire web application, while an app is a self-contained module that handles one specific feature (like notes, user accounts, etc.). A project can contain multiple apps.
-
Start a new project. In your terminal, choose an empty folder for the project and run:
django-admin startproject myproject # Change to the created directory cd myproject
-
Start a new app. Inside the project directory, run:
python manage.py startapp notesapp
Your folder structure should now look something like:
myproject/ ├── manage.py ├── myproject/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── notesapp/ ├── __init__.py ├── admin.py ├── models.py ├── views.py └── ... -
Register the app. Django needs to know about your app before it can use it. Open
myproject/settings.pyand add your new app (and DRF) to theINSTALLED_APPSlist:INSTALLED_APPS = [ ..., 'rest_framework', # enable Django REST Framework 'notesapp', # our app (replace with your app name) ... ]
Django uses SQLite by default for simple projects. To create the database and tables, run migrations. Migrations are Django's way of syncing your Python code with the database structure. They translate your models into actual database tables:
python manage.py migrateTip
After running this, you should see a new db.sqlite3 file in your project folder. This is your database!
CRUD stands for Create, Read, Update, Delete—the four basic operations you can do with data. A REST API lets other applications (like a mobile app or website) perform these operations over HTTP by sending requests to specific URLs (called endpoints).
Let's create a simple Notes app with title and content fields, exposed via a REST API.
-
Define the model. A model defines the structure of your data—think of it as a blueprint for a database table. Each field becomes a column. In
notesapp/models.py, add aNotemodel:from django.db import models class Note(models.Model): title = models.CharField(max_length=100) content = models.TextField() created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.title
This creates a
notesapp_notetable (after migrating) withid,title,content, andcreated_atcolumns. -
Create and apply migrations. After saving the model, you need to tell Django to update the database.
makemigrationscreates a migration file describing the changes, andmigrateapplies them:python manage.py makemigrations python manage.py migrate
Tip
You should see output mentioning the creation of the Note model.
-
Register in Admin. Django comes with a built-in admin panel where you can view and edit your data without writing any frontend code. Register the model in
notesapp/admin.py:from django.contrib import admin from .models import Note admin.site.register(Note)
Tip
To test the admin panel, first create a superuser by running python manage.py createsuperuser and following the prompts.
Then start the server (python manage.py runserver) and go to http://127.0.0.1:8000/admin/.
Log in and you should see "Notes" listed!
-
Create a serializer. When your API sends data to a browser or app, it needs to be in a format they can understand (usually JSON). A serializer handles this conversion. It turns Python objects into JSON (and vice versa). In
notesappfolder create a fileserializers.pyand add:from rest_framework import serializers from .models import Note class NoteSerializer(serializers.ModelSerializer): class Meta: model = Note fields = ['id', 'title', 'content', 'created_at']
Here, we create a class (
class NoteSerializer) that inherits from DRF'sModelSerializer, meaning we can use all methods that are implemented in that class. This saves us time by automatically figuring out how to map database fields to JSON fields so we don't have to write that logic manually.- The inner
Metaclass is used to provide configuration to the main class. model = Notetells the serializer exactly which Database Model it should look atfields = [...]explicitly defines which pieces of data should be included in the API. If you left 'created_at' out of this list, the API would hide that timestamp from the user.
- The inner
-
Create a ViewSet. A view handles incoming requests and returns responses. A
ViewSetbundles all the CRUD operations together, so you don't have to write separate functions for listing, creating, updating, and deleting. Innotesapp/views.py, add:from rest_framework import viewsets from .models import Note from .serializers import NoteSerializer class NoteViewSet(viewsets.ModelViewSet): queryset = Note.objects.all() serializer_class = NoteSerializer
In this case, by inheriting from
ModelViewSetourclass NoteViewSet(viewsets.ModelViewSet)gets the logic for Create, Read, Update, and Delete for free. We don't have to write the functions ourselves!queryset = Note.objects.all()defines the data source. It tells the view: "When someone asks for notes, look at theNotetable and getall()of them."serializer_class = NoteSerializerdefines the translator. It tells the view: "When you get that data, useNoteSerializerto turn it into JSON before sending it to the user."
-
Configure URLs. URLs define the endpoints of your API—the addresses where clients send requests. A router automatically generates standard REST URLs for your ViewSet (like
/api/notes/for listing and/api/notes/1/for a specific note). Createnotesapp/urls.pyand set up a router:from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import NoteViewSet router = DefaultRouter() router.register(r'notes', NoteViewSet) urlpatterns = [ path('api/', include(router.urls)), ]
Then include this in the project's
urls.py(myproject/urls.py):from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('notesapp.urls')), # include our app's URLs ]
Now the API will be accessible under
/api/notes/. -
Run the server. Start Django's development server:
python manage.py runserver
-
Go to http://127.0.0.1:8000/api/notes/ in your browser. You should see a list (likely empty) and a form to create new notes.
Tip
Try creating a note using the form at the bottom of the page! Fill in a title and content, then click POST. Your note should appear in the list above.
Your app should look something like the below:

If you run into errors, check out these common pitfalls:
- The Issue: On some systems (especially Mac/Linux), the command
pythonrefers to an old version (Python 2) or doesn't exist, whilepython3is the correct command. - The Fix: Refer to the
manage.pyscript. Ifpython manage.py ...fails, try runningpython3 manage.py ...instead. On Windows, you might also trypy manage.py ....
- The Issue: You likely installed Django, but your Virtual Environment (venv) is not active. Libraries are installed inside the environment, so if you aren't "inside" it, the computer can't find them.
- The Fix:
- Look at your terminal prompt. Does it start with
(venv)or(.venv)? - If not, activate it again:
- Windows:
venv\Scripts\activate - Mac/Linux:
source venv/bin/activate
- Windows:
- Once activated, try the command again.
- Look at your terminal prompt. Does it start with
- The Issue: You see "Permission denied" errors when running commands.
- The Fix: Avoid using
sudoto install packages globally. Ensure you are using a virtual environment (see above), which creates a safe space where you have full permissions.
- The Issue: SQLite throws a "database is locked" error.
- The Fix: This usually happens if you have a database viewer open (like 'DB Browser for SQLite') while the server is trying to write to it. Close any programs that are viewing the
db.sqlite3file and try again.
You now have a working backend engine. While "Notes" are simple, this exact same architecture powers Instagram, Pinterest, and Jira.
Here is how to take this template and twist it into the project you want to build.
The Note model is just a placeholder. Change models.py to fit your idea:
- Rename
Note->Product. - Fields:
price(DecimalField),stock_count(IntegerField),description(TextField).
(Remember: Every time you change models.py, run python manage.py makemigrations and python manage.py migrate!)
Real apps have data that relates to other data. You can link models using Foreign Keys.
- Create a
Categorymodel. - Add
category = models.ForeignKey(Category, on_delete=models.CASCADE)to yourNotemodel. - Now your API will let you link notes to specific categories!
You can read more about databases in their dedicated hackpack!
Hackathon projects love visuals. To let users upload images:
- Install the image handler:
pip install Pillow - Add a field to your model:
image = models.ImageField(upload_to='uploads/') - Add
imageto yourserializers.pyfields list. - Now your API accepts file uploads!
Your backend is running on port 8000. Now you need a frontend (React, Vue, Mobile App) to talk to it.
-
The Endpoint:
http://127.0.0.1:8000/api/notes/ -
The Fetch: Use standard HTTP requests.
// Example JavaScript fetch fetch('[http://127.0.0.1:8000/api/notes/](http://127.0.0.1:8000/api/notes/)') .then(response => response.json()) .then(data => console.log(data));
This topic is covered extensively in the API design HackPack.
Tip
If your frontend is blocked by "CORS" errors, install django-cors-headers. It's the most common "gotcha" when connecting frontends to backends!
Ready to move faster? If you're building a production-ready Django project or want to skip repetitive setup, check out Cookiecutter Django. It's a project template that automatically scaffolds a Django application with best practices, security settings, Docker configuration, and more built in. Great for when you've outgrown the basics and want a solid foundation for a real-world application.