← Назад к вопросам

В чем разница между Django, Django REST, FastAPI и Flask?

2.0 Middle🔥 161 комментариев
#Django#FastAPI и Flask#REST API и HTTP

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Разница между Django, Django REST Framework, FastAPI и Flask

Быстрое сравнение

ФакторFlaskDjangoDjango RESTFastAPI
РазмерМикрофреймворк (small)Full-stackExtension для DjangoModern async
Кривая обученияНизкаяСредняяСредняяНизкая
Встроенное ORMНетДа (ORM)Да (ORM)Нет
Admin панельНетДа (есть)РасширенаНет
Встроенные формыНетДаДа (сериализаторы)Нет
PerformanceХорошоСреднееСреднееОчень хорошо
Async/awaitLimitedDjango 3.1+Django 3.1+Native
API документацияРучнаяРучнаяВстроенаАвтоматическая
ProductionСреднееХорошееХорошееОтличное
МасштабируемостьДля микросервисовДля больших приложенийДля APIsДля микросервисов

1. Flask — микрофреймворк

Flask — это минималистичный фреймворк. Тебе нужно почти всё решить самому.

from flask import Flask, jsonify, request

app = Flask(__name__)

# Простой routing
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = {'id': user_id, 'name': 'John'}
    return jsonify(user)

@app.route('/users', methods=['POST'])
def create_user():
    data = request.json
    # Нужно самому валидировать!
    if not data.get('name'):
        return {'error': 'Name required'}, 400
    
    user = save_to_db(data)
    return jsonify(user), 201

if __name__ == '__main__':
    app.run(debug=True)

Когда использовать Flask:

  • Малые проекты (MVP, prototype)
  • Микросервисы
  • API с минимальным функционалом
  • Когда нужна максимальная гибкость
  • Learning (легче понять, как работает http)

Проблемы Flask:

  • Нет встроенного ORM
  • Нет встроенной валидации данных
  • Нет встроенного механизма аутентификации
  • Нужно вручную всё собирать
  • Для больших проектов становится сложным

2. Django — полнофункциональный фреймворк

Django — это всё включено. Есть всё для разработки больших приложений.

# models.py
from django.db import models

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

# views.py (функциональный подход)
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods

@require_http_methods(["GET"])
def get_user(request, user_id):
    try:
        user = User.objects.get(id=user_id)
        return JsonResponse({
            'id': user.id,
            'name': user.name,
            'email': user.email
        })
    except User.DoesNotExist:
        return JsonResponse({'error': 'Not found'}, status=404)

# views.py (классовый подход - лучше)
from django.views import View
from django.views.decorators.http import require_http_methods
from django.http import JsonResponse

class UserView(View):
    def get(self, request, user_id):
        try:
            user = User.objects.get(id=user_id)
            return JsonResponse({'id': user.id, 'name': user.name})
        except User.DoesNotExist:
            return JsonResponse({'error': 'Not found'}, status=404)
    
    def post(self, request):
        data = request.POST
        # Django Forms валидируют автоматически
        form = UserForm(data)
        if form.is_valid():
            user = form.save()
            return JsonResponse({'id': user.id})
        return JsonResponse({'errors': form.errors}, status=400)

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('users/<int:user_id>/', views.UserView.as_view()),
]

Встроенное в Django:

  • ORM — QuerySet для работы с БД
  • Admin панель — автоматическая административная панель
  • Forms — встроенная валидация форм
  • Middleware — система для обработки запросов
  • Шаблоны — встроенный template engine
  • Аутентификация — User model и auth system
  • Миграции — алембик для изменения БД

Когда использовать Django:

  • Крупные web приложения
  • Нужна админ панель
  • Нужна встроенная аутентификация
  • Когда scalability важна
  • Когда нужны встроенные инструменты

Проблемы Django:

  • Монолитный (всё вместе)
  • Для простого API излишен
  • Медленнее, чем микрофреймворки
  • Кривая обучения
  • Тяжелее для микросервисов

3. Django REST Framework — расширение Django для APIs

Django REST Framework (DRF) — это расширение Django для создания REST APIs.

# models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

# serializers.py (валидация и сериализация)
from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    author_name = serializers.StringRelatedField(source='author.name', read_only=True)
    
    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'author', 'author_name', 'created_at']
        read_only_fields = ['id', 'created_at']

# views.py (класс-представление)
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated

class PostListCreate(generics.ListCreateAPIView):
    """Получить список постов или создать новый"""
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [IsAuthenticated]
    
    def perform_create(self, serializer):
        # Автоматически устанавливаем автора
        serializer.save(author=self.request.user)

class PostDetailView(generics.RetrieveUpdateDestroyAPIView):
    """Получить, обновить или удалить пост"""
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [IsAuthenticated]

# urls.py
from rest_framework.routers import DefaultRouter
from . import views

urlpatterns = [
    path('posts/', views.PostListCreate.as_view()),
    path('posts/<int:pk>/', views.PostDetailView.as_view()),
]

Особенности DRF:

  • Сериализаторы — валидация и преобразование данных
  • Permissions — встроенная система прав (IsAuthenticated, IsAdminUser)
  • Throttling — ограничение количества запросов
  • Pagination — встроенная пагинация
  • Filtering — встроенная фильтрация
  • API Documentation — встроенная браузируемая документация
  • Authentication — встроенные методы аутентификации
# Пример с пермишнами и фильтрацией
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.filters import SearchFilter, OrderingFilter
from rest_framework.pagination import PageNumberPagination

class PostListCreate(generics.ListCreateAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [IsAuthenticated]
    filter_backends = [SearchFilter, OrderingFilter]
    search_fields = ['title', 'content']
    ordering_fields = ['created_at', 'title']
    pagination_class = PageNumberPagination

# Запросы:
# GET /posts/?search=django&ordering=-created_at&page=1
# ↓ Автоматическая фильтрация, сортировка и пагинация

Когда использовать DRF:

  • Создание REST API на базе Django
  • Когда нужна встроенная валидация сериализаторов
  • Когда нужны пермишны и аутентификация
  • Когда нужна встроенная документация

Проблемы DRF:

  • Медленнее, чем FastAPI
  • Всё ещё привязан к Django ORM
  • Для простого API может быть излишним

4. FastAPI — современный async фреймворк

FastAPI — это современный фреймворк для создания быстрых APIs.

from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel, EmailStr
from typing import Optional
from datetime import datetime

app = FastAPI()

# Pydantic модели (автоматическая валидация!)
class UserCreate(BaseModel):
    name: str
    email: EmailStr  # Автоматически валидирует email
    age: Optional[int] = None
    
    class Config:
        json_schema_extra = {
            "example": {
                "name": "John Doe",
                "email": "john@example.com",
                "age": 25
            }
        }

class UserResponse(BaseModel):
    id: int
    name: str
    email: str
    created_at: datetime

# Dependency injection для аутентификации
async def get_current_user(token: str = Header(...)):
    # Валидируем токен
    if not is_valid_token(token):
        raise HTTPException(status_code=401, detail="Invalid token")
    return get_user_by_token(token)

# Async endpoints (очень быстро!)
@app.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int):
    """Получить пользователя по ID"""
    user = await db.get_user(user_id)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user

@app.post("/users", response_model=UserResponse, status_code=201)
async def create_user(
    user_data: UserCreate,
    current_user = Depends(get_current_user)  # Требует аутентификации
):
    """Создать нового пользователя (требует auth)"""
    # Pydantic автоматически валидирует!
    # - name — строка
    # - email — валидный email
    # - age — опционально, целое число
    
    user = await db.create_user(user_data)
    return user

@app.get("/users", response_model=list[UserResponse])
async def list_users(
    skip: int = 0,
    limit: int = 10,
    current_user = Depends(get_current_user)
):
    """Получить список пользователей с пагинацией"""
    users = await db.get_users(skip=skip, limit=limit)
    return users

Плюсы FastAPI:

  • Async нативно — встроенная поддержка async/await
  • Очень быстро — одна из самых быстрых фреймворков
  • Pydantic валидация — автоматическая валидация данных
  • Автоматическая документация — Swagger UI и ReDoc
  • Type hints — полная поддержка типов (MyPy)
  • Зависимости — встроенная система dependency injection
  • Асинхронная БД — легко интегрируется с async БД (asyncpg, motor)
# Автоматическая документация по типам!
# Swagger: http://localhost:8000/docs
# ReDoc: http://localhost:8000/redoc

# Pydantic валидирует автоматически:
# POST /users
# {
#   "name": "John",
#   "email": "invalid-email",  # ← Ошибка 422!
#   "age": "not-a-number"       # ← Ошибка 422!
# }

Когда использовать FastAPI:

  • Современные REST APIs
  • Когда нужна производительность
  • Микросервисы с async
  • Когда нужна типизация
  • Когда нужна быстрая разработка

Проблемы FastAPI:

  • Молодой проект (может быть нестабильность)
  • Нет встроенного ORM (нужно интегрировать SQLAlchemy)
  • Нет встроенной админ панели
  • Нет встроенных форм (для веба)

Сравнение по примеру: API для списка задач

Flask версия

from flask import Flask, request, jsonify
app = Flask(__name__)

tasks = {}

@app.route('/tasks', methods=['POST'])
def create_task():
    data = request.json
    if not data or 'title' not in data:
        return {'error': 'Title required'}, 400
    
    task_id = len(tasks) + 1
    tasks[task_id] = {'id': task_id, 'title': data['title']}
    return jsonify(tasks[task_id]), 201

@app.route('/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):
    if task_id not in tasks:
        return {'error': 'Not found'}, 404
    return jsonify(tasks[task_id])

Django версия

# models.py
from django.db import models

class Task(models.Model):
    title = models.CharField(max_length=200)

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('tasks/', views.create_task),
    path('tasks/<int:task_id>/', views.get_task),
]

# views.py
from django.http import JsonResponse
from .models import Task

def create_task(request):
    if request.method == 'POST':
        title = request.POST.get('title')
        task = Task.objects.create(title=title)
        return JsonResponse({'id': task.id, 'title': task.title})

def get_task(request, task_id):
    try:
        task = Task.objects.get(id=task_id)
        return JsonResponse({'id': task.id, 'title': task.title})
    except Task.DoesNotExist:
        return JsonResponse({'error': 'Not found'}, status=404)

Django REST Framework версия

# serializers.py
from rest_framework import serializers
from .models import Task

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = ['id', 'title']

# views.py
from rest_framework import generics
from .models import Task
from .serializers import TaskSerializer

class TaskListCreate(generics.ListCreateAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

class TaskDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

# urls.py
from rest_framework.routers import SimpleRouter
from . import views

urlpatterns = [
    path('tasks/', views.TaskListCreate.as_view()),
    path('tasks/<int:pk>/', views.TaskDetail.as_view()),
]

FastAPI версия

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class TaskCreate(BaseModel):
    title: str

class TaskResponse(BaseModel):
    id: int
    title: str

tasks = {}
task_counter = 0

@app.post("/tasks", response_model=TaskResponse, status_code=201)
async def create_task(task: TaskCreate):  # ← Автоматическая валидация!
    global task_counter
    task_counter += 1
    tasks[task_counter] = {'id': task_counter, 'title': task.title}
    return tasks[task_counter]

@app.get("/tasks/{task_id}", response_model=TaskResponse)
async def get_task(task_id: int):  # ← Type hint!
    if task_id not in tasks:
        return {'error': 'Not found'}, 404
    return tasks[task_id]

Вывод: какой выбрать?

СценарийВыбор
Простой API, MVPFlask
Большое веб-приложение с админкойDjango
REST API на базе DjangoDjango REST Framework
Современный, быстрый APIFastAPI
МикросервисыFlask + FastAPI
Когда нужна максимальная производительностьFastAPI
Когда нужна экосистема пакетовDjango

Рекомендация для 2024:

  • Новые проекты → FastAPI (лучший выбор для современной разработки)
  • Существующие Django проекты → остаться в Django
  • Микросервисы → FastAPI или Flask
  • Лучше выучить FastAPI + SQLAlchemy, чем Django REST Framework