Migrating a fullstack Django app to use Svelte, SvelteKit and Django Ninja (Part 1)
In this post, I'm starting to convert my full-stack Django app (Happiness Unleashed) to use Django for the backend and Svelte on the front end. Happiness Unleashed is project for a Hackathon I did with Hilla Muraja, Felipe Zanetti, Soundarya Kantimahanti, Claudio Cruz, Ann Edvinsson and Florian Guldner. The aim of the app is to spread happiness through acts of kindness that you can carry out each day and share with your friends and family.
The first part of the process involves setting up the backend APIs using Django Ninja, ensuring our data can be accessed from the frontend built with Svelte and SvelteKit.
You can find the original repo and deployed site here:
The new version of the project isn't yet deployed, but you can find the repo here:
Initial Setup
Project Structure
Before diving into the API development, the first step is to break up the frontend and backend. The original project used Django templates, but they will be taken out. We'll create two main directories: frontend and backend. To help see the data in use on the frontend, I also created the Svelte app in the frontend
folder.
The .venv
folder
I first moved into the backend
folder to create my virtual environment. That allows to me only have packages in my requirements.txt
that are specific to the project. I am on a Mac, so the commands are slightly different that on Windows. The command to create the virtual environment is:
python3 -m venv .venv
Once created, it then needs to be activated. This can be done by running this command:
source .venv/bin/activate
Installing Django Ninja
To start, I installed Django Ninja, a fast, type-safe web framework for building APIs with Django. I installed it using pip install django-ninja
.
Handling Cross-Origin Resource Sharing (CORS)
Since the frontend and backend are now separate entities, configuring Cross-Origin Resource Sharing (CORS) is essential to allow the Svelte frontend to communicate with the Django backend. This involves installing the django-cors-headers
package:
pip install django-cors-headers
Then, I added it to the installed apps and middleware in settings.py
:
INSTALLED_APPS = [ ... 'corsheaders', ... ] MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', ... ]
For the allowed origins, I just needed to add the localhost that my Svelte app was running on:
CORS_ALLOWED_ORIGINS = [ "http://localhost:5173", ]
Building the API
Creating the First Route
The initial API route was set up using Django Ninja in the api.py
file of the project's main (happiness_unleashed
) folder. This simple endpoint returns a greeting, which is useful for confirming that the backend can communicate with the frontend:
from ninja import NinjaAPI api = NinjaAPI() @api.get("/hello") def hello(request): return {"message": "Hello from Django Ninja!"}
Structuring the API with Routers
To organise the API effectively, routers were used to separate the handling of different data models:
- Main API Router:
In the main
api.py
, a NinjaAPI instance was created:
from ninja import NinjaAPI from acts_of_kindness.api import router as acts_router api = NinjaAPI() api.add_router('/acts', acts_router)
- Other apps:
In each of the other apps, I created an
api.py
file that contains the API router, which is a way to split the API. For example, theapi.py
code for theacts_of_kindness
app looks like this:
from ninja import Router from .models import ActsOfKindness from .schemas import ActsOfKindnessSchema router = Router() @router.get("/five-acts", response=list) def five_random_acts(request): acts = ActsOfKindness.objects.all().order_by('?')[:5] return acts
Pydantic for Data Validation
Using Pydantic, data validation schemas were defined in the schemas.py
files within each Django app:
from ninja import ModelSchema from .models import ActsOfKindness class ActsOfKindnessSchema(ModelSchema): class Meta: model = ActsOfKindness fields = ['name', 'description', 'image', 'approved', 'user_profiles']
Automatic Documentation
Something I thought was really cool is that Django Ninja automatically generates Swagger documentation for the API, which is accessible at /api/docs
. This feature makes testing and integration easier for frontend developers.
Conclusion
This post covered the initial setup and configuration of Django Ninja for creating APIs in a Django project that is being transitioned to use Svelte and SvelteKit on the frontend. The next parts will delve into refining the API and setting up authentication using Django Allauth Headless.