FastAPI vs Django

By Frederick Ngoiya

June 30, 2024, 11:49 a.m.

Django vs FastAPI: A Technical Comparison for API Development

fastapi vs django




1. Database and Data Modeling


Django Data Modeling


  1. Uses a robust ORM with built-in models

  2. Supports multiple databases out of the box

  3. Provides database migrations


Example : Django Model Class


class User(models.Model):
    username = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    created_at = models.DateTimeField(auto_now_add=True)

Django Serializer Class

class UserSerializer(serializers.ModelSerializer):
class Meta: 
	model = User 
	fields = ['username', 'email', 'created_at']

API Class
class UserList(generics.ListAPIView): 
	queryset = User.objects.all() 
	serializer_class = UserSerializer



 FastAPI Data Modeling

  1. No built-in ORM, but can integrate with SQLAlchemy or other ORMs

  2. Typically used with Pydantic for data validation and serialization






Example: Using Sqlachemy


from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    username = Column(String, unique=True, index=True)
    email = Column(String, unique=True, index=True)

Schema
from pydantic import BaseModel 
class UserBase(BaseModel):
	username: str | None
	email: str class 
	Config: orm_mode = True 

class User(UserBase): 
	id: int



2. ORM (Object-Relational Mapping)


Django

  1. - Built-in ORM with powerful querying capabilities

  2. - Supports complex relationships and joins


Example:

Querying with Django ORM
users = User.objects.filter(email__endswith="@example.com").order_by("-created_at")



 FastAPI

  1. - Often used with SQLAlchemy ORM

  2. - Requires more setup but offers flexibility


Example

from sqlalchemy.orm import Session
def get_users(db: Session, skip: int = 0, limit: int = 100):
    return db.query(User).offset(skip).limit(limit).all() 


3. Background Tasks


Django

  1. Celery is commonly used for background tasks

  2. Built-in support for running background tasks with Django Q


Example:

from django.core.mail import send_mail
from django_q.tasks import async_task

def send_welcome_email(user_id):
    user = User.objects.get(id=user_id)
    send_mail(
        "Welcome!",
        f"Hello {user.username}, welcome to our platform!",
        "from@example.com",
        [user.email],
    )

Queueing a background task

async_task(send_welcome_email, user.id)


FastAPI

  1. Built-in support for background tasks using `BackgroundTasks`

  2. Can integrate with Celery or other task queues for more complex scenarios


Example:

from fastapi import BackgroundTasks
def send_welcome_email(user_email: str):

    # Code to send email

@app.post("/users/")
async def create_user(user: User, background_tasks: BackgroundTasks):
    # Save user to database
    background_tasks.add_task(send_welcome_email, user.email)
    return {"message": "User created"}



4. Static Files


Django

  1. Built-in support for handling static files

  2. Provides `collectstatic` management command for production


Example:

# settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
    # Your URL patterns
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)



FastAPI

  1. No built-in static file handling

  2. Often used with third-party libraries like `aiofiles` or served separately using a web server like Nginx


Example:

from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")



Conclusion


Django: Full-featured framework with built-in solutions for common web development tasks

FastAPI: Lightweight, high-performance framework focused on API development with modern Python features



Learn FastAPI