Query-параметры¶
djo определяет query-параметры двумя способами, отдавая предпочтение первому, если доступны оба: типизированная сигнатура хендлера, либо обращения к request.GET в исходнике.
Типизированная сигнатура хендлера¶
Любой дополнительный параметр хендлера — помимо request/self/path-параметров — с обычной типовой аннотацией читается напрямую, без регулярных выражений и угадывания:
Для GET/DELETE-хендлеров такие параметры становятся query-параметрами; параметр считается required, если у него нет значения по умолчанию. Поддерживаются аннотации str, int, float, bool, list/list[T], dict, uuid.UUID, datetime.date, datetime.datetime, decimal.Decimal, а также Optional[T]/T | None.
Django не привязывает эти значения за вас
Аннотация name: str здесь — это только подсказка для djo, что писать в документации. Собственный диспетчер Django никогда не заполняет дополнительные параметры view из query-строки или тела запроса (маршрутизация path() так не работает). Хендлеру всё равно нужно самому прочитать request.GET/request.data; аннотация — это лишь точный, явный сигнал типа для схемы.
Резервный вариант: чтение исходника¶
Без типизированной сигнатуры djo читает исходник хендлера в поисках обращений к request.GET и превращает их в query-параметры OpenAPI — включая тип и обязательность.
def search_users(request):
"""Search users by name."""
query = request.GET.get("q", "")
page = request.GET.get("page", 1)
return JsonResponse({"query": query, "page": page, "results": []})
Развёрнуто в Swagger UI:

Как определяются тип и обязательность¶
| Паттерн в исходнике | required |
schema |
|---|---|---|
request.GET["tag"] |
true |
{"type": "string"} (у обращения через [...] нет значения по умолчанию для определения типа) |
request.GET.get("page", 1) |
false |
{"type": "integer"} — тип определён из литерала по умолчанию |
request.GET.get("active", True) |
false |
{"type": "boolean"} |
request.GET.get("q", "") |
false |
{"type": "string"} |
request.GET.get("tag") |
false |
{"type": "string"} (нет значения по умолчанию для определения типа) |
Правило простое: обращение через [...] означает, что код упадёт с KeyError, если параметра нет — значит, он обязателен. .get(...) всегда имеет запасной вариант, значит, параметр опционален — а если этот запасной вариант является литералом, его Python-тип становится типом параметра в OpenAPI.
Типизируются только литеральные значения по умолчанию
request.GET.get("page", DEFAULT_PAGE) — где значение по умолчанию является переменной, а не литералом — всё равно даст корректный (опциональный, строкового типа) параметр; djo просто не сможет определить более точный тип из имени, которое не может разрешить статически.