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.

Image description

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:

New Happiness Unleashed Repo

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:

  1. 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)
  1. 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, the api.py code for the acts_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

Image description

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.

Image description

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.

ApiSvelteDjango NinjaDjangoSveltekit
Avatar for Stephen

Written by Stephen

I am a fullstack developer who likes to build useful things.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.