Перейти к основному содержимому

Первая программа на Django REST Framework

Разработчику
Загрузка симулятора первой программы…

Первая программа на Django REST Framework

От HTML к JSON

Первая программа на Django заканчивается HTML-страницей в браузере и админкой /admin. В реальных проектах тот же бэкенд часто отдаёт JSON — текстовый формат, который удобно читать JavaScript, мобильным приложениям и другим сервисам.

Пример JSON-ответа:

[
{"id": 1, "text": "Купить молоко", "created_at": "2026-05-26T10:00:00Z"}
]

Django REST Framework (DRF) — надстройка над Django, которая превращает модели БД в такой API с минимумом кода.

Если проект ещё не на Django и нужен только API — смотрите FastAPI. DRF выигрывает, когда уже есть Django: ORM, auth, админка, одна кодовая база.


Словарь DRF

ТерминПростыми словами
APIНабор URL, по которым клиент получает и меняет данные
СериализаторКласс: «какие поля модели уйти в JSON» + проверка входа
ViewSetОдин класс с методами list, create, retrieve, update, destroy
RouterАвтоматически создаёт URL вроде /api/notes/ и /api/notes/1/
Browsable APIHTML-страница DRF для ручной отладки POST/GET в браузере
QuerySet«Запрос к БД», который Django выполнит позже: Note.objects.all()

Что получится

Метод HTTPURLДействие
GET/api/notes/Список заметок
POST/api/notes/Создать: тело {"text": "..."}
GET/api/notes/1/Одна заметка с id=1
PUT/PATCH/api/notes/1/Изменить (ModelViewSet умеет)
DELETE/api/notes/1/Удалить

Слэш в конце URL (/notes/) — важная деталь Django: без него часто будет редирект 301.


Подготовка проекта

Продолжите проект из 3011.md или создайте новый:

python -m venv venv
# Windows — venv\Scripts\activate
# macOS/Linux — source venv/bin/activate

pip install django djangorestframework
django-admin startproject notes_project
cd notes_project
python manage.py startapp notes

startproject — каркас с settings.py и urls.py. startapp notes — приложение с models.py, куда кладут модель «Заметка».

Регистрация в settings.py

INSTALLED_APPS = [
# ...
'rest_framework',
'notes',
]

Django подхватывает только приложения из этого списка. Без 'rest_framework' импорты from rest_framework import ... упадут с ModuleNotFoundError.


Модель — что хранится в БД

notes/models.py:

from django.db import models

class Note(models.Model):
text = models.CharField(max_length=500)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.text[:50]
ПолеСмысл
CharField(max_length=500)Строка до 500 символов
DateTimeField(auto_now_add=True)Время создания ставится один раз при INSERT
__str__Как запись выглядит в админке

Создание таблиц в БД:

python manage.py makemigrations # файл миграции в git
python manage.py migrate # применить к SQLite/PostgreSQL

Миграция — версионированное изменение схемы. Вы изменили модель — снова makemigrations + migrate.


Сериализатор — мост модель ↔ JSON

notes/serializers.py:

from rest_framework import serializers
from .models import Note

class NoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note
fields = ['id', 'text', 'created_at']
read_only_fields = ['id', 'created_at']

Разбор:

  • ModelSerializer — DRF сам построит поля по модели Note.
  • fields — белый список: в JSON попадут только эти ключи.
  • read_only_fields — клиент при POST не может подставить свой id или created_at; сервер выставит сам.

При POST с пустым text DRF вернёт 400 с описанием полей — отдельный if not text в каждом view писать не нужно.

Пример ошибки:

{"text": ["This field may not be blank."]}

ViewSet — вся CRUD-логика в одном классе

notes/views.py:

from rest_framework import viewsets
from .models import Note
from .serializers import NoteSerializer

class NoteViewSet(viewsets.ModelViewSet):
queryset = Note.objects.all().order_by('-created_at')
serializer_class = NoteSerializer
АтрибутСмысл
querysetОткуда брать объекты для list/retrieve/update/delete
order_by('-created_at')Сначала новые заметки
ModelViewSetВключает list, create, retrieve, update, partial_update, destroy

Раньше в «голом» Django писали отдельную функцию на каждое действие. ViewSet группирует их по ресурсу Note.


Router — автоматические URL

notes_project/urls.py:

from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from notes.views import NoteViewSet

router = DefaultRouter()
router.register('notes', NoteViewSet, basename='note')

urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]

router.register('notes', ...) создаёт маршруты:

  • GET/POST/api/notes/
  • GET/PUT/PATCH/DELETE/api/notes/<pk>/

basename='note' — имя для reverse в тестах (reverse('note-list')).


Запуск и проверка

python manage.py runserver

В браузере (Browsable API)

Откройте http://127.0.0.1:8000/api/notes/ — форма DRF: можно отправить POST с полем text без Postman.

curl — как это видит скрипт

Список:

curl http://127.0.0.1:8000/api/notes/

Создание:

curl -X POST http://127.0.0.1:8000/api/notes/ \
-H "Content-Type: application/json" \
-d "{\"text\": \"Первая заметка через DRF\"}"
Часть командыСмысл
-X POSTМетод HTTP
Content-Type: application/jsonТело — JSON
-d "{...}"Тело запроса

Ответ при успехе — 201 Created и JSON с id, text, created_at.


Разрешения (важно для production)

По умолчанию настройки DRF могут требовать авторизацию. Для локальной отладки иногда явно разрешают всем:

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
}

Для боевого API замените на IsAuthenticated и подключите сессии Django, токены или JWT (djangorestframework-simplejwt). Иначе любой в интернете сможет читать и удалять ваши данные.


Как DRF связан с обычным Django

СлойОбычный Django (3011)DRF
Данныеmodels.ModelТа же модель
ОтветHTML-шаблонJSON через сериализатор
Вход формыrequest.POSTJSON в request.data
URLpath('...', view)Router + ViewSet

Фронт на React делает fetch('/api/notes/') и рисует список без серверного HTML.


Частые ошибки

СимптомПричинаРешение
404 на /api/notesНет завершающего /Запрос на /api/notes/
Пустой список после POSTPOST на неверный URL или 400Смотреть тело ответа и статус
ModuleNotFoundError: rest_frameworkНе в INSTALLED_APPSДобавить приложение
403 ForbiddenСтрогие permissionsAllowAny локально или login

Что попробовать дальше

  1. SearchFilterGET /api/notes/?search=молоко.
  2. PageNumberPagination — постраничный список в REST_FRAMEWORK.
  3. Сравнить тот же сценарий «заметки» с Flask и FastAPI.
  4. Тесты API — pytest + APIClient из DRF.

Связанные материалы


См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).