← Назад к вопросам
В чем разница между 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
Быстрое сравнение
| Фактор | Flask | Django | Django REST | FastAPI |
|---|---|---|---|---|
| Размер | Микрофреймворк (small) | Full-stack | Extension для Django | Modern async |
| Кривая обучения | Низкая | Средняя | Средняя | Низкая |
| Встроенное ORM | Нет | Да (ORM) | Да (ORM) | Нет |
| Admin панель | Нет | Да (есть) | Расширена | Нет |
| Встроенные формы | Нет | Да | Да (сериализаторы) | Нет |
| Performance | Хорошо | Среднее | Среднее | Очень хорошо |
| Async/await | Limited | Django 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, MVP | Flask |
| Большое веб-приложение с админкой | Django |
| REST API на базе Django | Django REST Framework |
| Современный, быстрый API | FastAPI |
| Микросервисы | Flask + FastAPI |
| Когда нужна максимальная производительность | FastAPI |
| Когда нужна экосистема пакетов | Django |
Рекомендация для 2024:
- Новые проекты → FastAPI (лучший выбор для современной разработки)
- Существующие Django проекты → остаться в Django
- Микросервисы → FastAPI или Flask
- Лучше выучить FastAPI + SQLAlchemy, чем Django REST Framework