Skip to content

RealWord is a medium clone. This implementation uses Django Ninja to create a backend service for the blog.

License

Notifications You must be signed in to change notification settings

c4ffein/realworld-django-ninja

Repository files navigation

RealWorld Example App

Django Ninja + Postgres codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld spec and API.

This codebase was created to demonstrate a fully fledged fullstack application built with Django Ninja including CRUD operations, authentication, routing, pagination, and more.

It is using the realWorld-DjangoRestFramework repository from Sean-Miningah as a base, as porting an app from Django REST framework to Django Ninja is an interesting process, and helps you realize that you may do it on your own codebase without having to change anything related to your Django models.

So credit is due to Sean-Miningah for any initial code.

For more information on how to this works with other frontends/backends, head over to the RealWorld repo.

About RealWorld

The RealWorld Demo App includes many implementations of the same project (a Medium clone), for which all frontends and backends are supposed to be switchable from one another as they all follow the same API.

It is supposed to reflect something similar to an early-stage startup's MVP, contrarily to some demo apps that are either too little or too much complex, and provide a good way to assert differences between frameworks.

This repository has been accepted as the reference implementation for Django Ninja, see the Python category for the RealWorld Demo App.

Django Ninja is an overlay to Django which lets you create APIs while being heavily inspired by FastAPI. It means it tries to stay as simple as possible for the API creation, while letting you benefit from the whole Django ecosystem, including its ORM, its auth system, even its HTML templates if you still need those...

Django Ninja is a very good alternative to Django REST framework, as it tries to be less unnecessarily complex and more performant.

As Django Ninja (and by extension this repository) only covers the API part, you may then connect a frontend to it after deploying.

Usage

  1. Clone the Git repository
  git clone https://github.com/c4ffein/realworld-django-ninja.git
  1. Create uv Virtual Environment
  cd realworld-django-ninja
  pip install uv  # Install the `extremely fast Python package installer and resolver`
  uv venv venv  # Create a venv
  . venv/bin/activate  # Activate it
  uv pip install .[dev]  # Install all dependencies for dev
  1. Apply Django migrations
  # Apply migrations to the SQLite database
  DEBUG=True python manage.py migrate
  # OR
  # Apply migrations to the specified PostgreSQL database
  DATABASE_URL=postgresql://user:password@netloc:port/dbname python manage.py migrate
  1. Run Application
  # Run in `DEBUG` mode with default settings, connected to the SQLite database
  make run-debug
  # OR
  # Run outside of `DEBUG` mode, connected to the specified PostgreSQL database
  make run DATABASE_URL=postgresql://user:password@netloc:port/dbname ALLOWED_HOSTS=*

The API Documentation should then be available at http://localhost:8000/docs

Using Docker and Docker Compose instead

Run:

docker compose up

If you want to rebuild the Docker Image:

docker compose up --build

Testing

  • make test-django: Django Ninja tests, uses SQLite by default, specify DATABASE_URL to use PostgreSQL.
  • make test-cypress-api: API Cypress tests (needs the application running).
    • make setup-cypress is needed to install the dependencies.

Deploying

A Django Ninja project can be deployed just as any Django project.
The documentation is near perfect.

Connect a frontend

Choose a frontend from codebase.show and configure it as required.
Some are already included in fronts as git submodules for your convenience:

You must make submodule to download those (or just git pull --recurse-submodules): the regular git pull doesn't get the updated submodule code when the reference in this repository is updated by someone else.

Description react-redux-realworld-example-app vue3-realworld-example-app
Install dependencies make front-setup-react make front-setup-vue
Run frontend make front-run-react make front-run-vue
Clean dependencies make front-clean-react make front-clean-vue

By default, the frontends try to reach the backend at http://localhost:8000, but this may be configured with the API_URL variable (either as make front-run-XXX API_URL="http://26.42.13.37:8000" or API_URL="http://26.42.13.37:8000" make front-run-XXX).

API Documentation

An auto-generated API documentation using Swagger is available at the /docs route.

Divergence with the existing, and porting process

Divergence with the RealWorld API spec

  • While the RealWorld API spec uses the HTTP 422 for most errors, we are not just using an array but the output from the default ValidationError handler.
  • This project handles some HTTP error codes differently:
    • Makes a difference between 401 and 403.
    • Uses 409 sometimes.
  • Some additional checks for data consistency (example: now verifies that email addresses are indeed email addresses and not just random strings, that change made some e2e tests failed).

Commits that are a good illustration of the migration from Django REST framework to Django Ninja

Before the heaviest modifications, some small commits have been made with the intention to well present the migration process.
Please note that many tests were added after and not before the migration, as, even if in a real world scenario you would try to add as-much tests before (to ensure that you don't break anything), the goal here was mainly to provide a Django Ninja of the RealWorld demo app. See Divergence with the existing.

  • df3f024a: Good example of migrating just one route.
    • Focused on the quick fix of the /api/articles/tag route in articles/api.py, and the modification of articles/urls.py that lets that route be handled by the Django Ninja router.
    • UT is adapted, the existing Django REST framework ViewSet deleted.
  • e5efe9c3: Migrating the comments app (tests pass but the route is broken as the router is only registered in 069cb7a7).
  • 45e472e0: Most modifications of the accounts app.
  • 069cb7a7: Preparing the migration of articles.
  • e7285493: Biggest chunk of modification towards the migration of the articles app.

Contributing

If you would like to contribute to the project, please follow these guidelines:

  • Fork the repository and create a new branch for your feature or bug fix.
  • Make the necessary changes and commit them.
    • make lint your changes, otherwise they will be rejected by the CI.
  • Push your changes to your forked repository.
  • Submit a pull request to the main repository, explaining the changes you made and any additional information that might be helpful for review.

Opened issues

You may check the opened issues if you want to make your first contributions, priority to this one.

Should I create an issue?

Seriously, yes, for anything that crosses your mind. This is early-stage, I'll consider any opinion.

License

About

RealWord is a medium clone. This implementation uses Django Ninja to create a backend service for the blog.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published