Skip to content
Merged
210 changes: 210 additions & 0 deletions djangostart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
# Django Backend HackPack

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.

## Prerequisites & Setup

1. **Install Python (3.8+).**

- **Windows:** Download from [python.org](https://www.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:

```bash
sudo apt update
sudo apt install python3 python3-pip
```

2. **Verify installation** by running `python3 --version` and `pip3 --version` (should show Python 3.x).

> ✅ **Checkpoint:** 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!

3. **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:

```bash
python3 -m venv venv
# Activate it:
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activate
```

> ✅ **Checkpoint:** After activation, you should see `(venv)` at the beginning of your terminal prompt. This confirms you're working inside the virtual environment.

4. **Install Django and DRF.** With Python ready, install the required packages via `pip`:

```bash
pip install django djangorestframework
```

> ✅ **Checkpoint:** Run `pip list` to verify. You should see `Django` and `djangorestframework` in the list of installed packages.

## Creating a Django Project and App

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.

1. **Start a new project.** In your terminal, choose an empty folder for the project and run:

```bash
django-admin startproject myproject
# Change to the created directory
cd myproject
```

2. **Start a new app.** Inside the project directory, run:

```bash
python manage.py startapp notesapp
```

> ✅ **Checkpoint:** You should now have a folder structure like this:
> ```
> myproject/
> ├── manage.py
> ├── myproject/
> │ ├── __init__.py
> │ ├── settings.py
> │ ├── urls.py
> │ └── wsgi.py
> └── notesapp/
> ├── __init__.py
> ├── admin.py
> ├── models.py
> ├── views.py
> └── ...
> ```

3. **Register the app.** Django needs to know about your app before it can use it. Open `myproject/settings.py` and add your new app (and DRF) to the `INSTALLED_APPS` list:

```python
INSTALLED_APPS = [
...,
'rest_framework', # enable Django REST Framework
'notesapp', # our app (replace with your app name)
...
]
```

## Database Setup (SQLite)

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:

```bash
python manage.py migrate
```

> ✅ **Checkpoint:** After running this, you should see a new `db.sqlite3` file in your project folder. This is your database!

## Building a Simple CRUD API (Notes)

**CRUD** stands for **C**reate, **R**ead, **U**pdate, **D**elete—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.

1. **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 a `Note` model:

```python
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_note` table (after migrating) with `id`, `title`, `content`, and `created_at` columns.

2. **Create and apply migrations.** After saving the model, you need to tell Django to update the database. `makemigrations` creates a migration file describing the changes, and `migrate` applies them:

```bash
python manage.py makemigrations
python manage.py migrate
```

> ✅ **Checkpoint:** You should see output mentioning the creation of the `Note` model.

3. **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`:

```python
from django.contrib import admin
from .models import Note
admin.site.register(Note)
```

> ✅ **Checkpoint:** 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/](http://127.0.0.1:8000/admin/). Log in and you should see "Notes" listed!

4. **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 `notesapp` folder create a file `serializers.py` and add:

```python
from rest_framework import serializers
from .models import Note

class NoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note
fields = ['id', 'title', 'content', 'created_at']
```

5. **Create a ViewSet.** A *view* handles incoming requests and returns responses. A `ViewSet` bundles all the CRUD operations together, so you don't have to write separate functions for listing, creating, updating, and deleting. In `notesapp/views.py`, add:

```python
from rest_framework import viewsets
from .models import Note
from .serializers import NoteSerializer

class NoteViewSet(viewsets.ModelViewSet):
queryset = Note.objects.all()
serializer_class = NoteSerializer
```

A `ModelViewSet` provides all CRUD operations (list, retrieve, create, update, delete) automatically.

6. **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). Create `notesapp/urls.py` and set up a router:

```python
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`):

```python
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/`.

7. **Run the server.** Start Django's development server:

```bash
python manage.py runserver
```

8. Go to [http://127.0.0.1:8000/api/notes/](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.

> ✅ **Checkpoint:** 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.

It should look as follows:
![webpage image](images/image.png)
Binary file added djangostart/db.sqlite3
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
16 changes: 16 additions & 0 deletions djangostart/djangostart/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
ASGI config for djangostart project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/6.0/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangostart.settings')

application = get_asgi_application()
119 changes: 119 additions & 0 deletions djangostart/djangostart/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"""
Django settings for djangostart project.

Generated by 'django-admin startproject' using Django 6.0.1.

For more information on this file, see
https://docs.djangoproject.com/en/6.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/6.0/ref/settings/
"""

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-a2b8z=71+j8bj$m-o1^s(i%4_8u#@nxyja%4m-$nsn#(p-57rf'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'notesapp',
]

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'djangostart.urls'

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

WSGI_APPLICATION = 'djangostart.wsgi.application'


# Database
# https://docs.djangoproject.com/en/6.0/ref/settings/#databases

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


# Password validation
# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]


# Internationalization
# https://docs.djangoproject.com/en/6.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/6.0/howto/static-files/

STATIC_URL = 'static/'
23 changes: 23 additions & 0 deletions djangostart/djangostart/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
URL configuration for djangostart project.

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/6.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
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
]
16 changes: 16 additions & 0 deletions djangostart/djangostart/wsgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
WSGI config for djangostart project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/6.0/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangostart.settings')

application = get_wsgi_application()
Binary file added djangostart/images/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading