Skip to content

Query-параметры

djo определяет query-параметры двумя способами, отдавая предпочтение первому, если доступны оба: типизированная сигнатура хендлера, либо обращения к request.GET в исходнике.

Типизированная сигнатура хендлера

Любой дополнительный параметр хендлера — помимо request/self/path-параметров — с обычной типовой аннотацией читается напрямую, без регулярных выражений и угадывания:

def create_user_typed(request, name: str = "", age: int = 0, active: bool = True):
    ...

Для 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:

Query-параметры

Как определяются тип и обязательность

Паттерн в исходнике 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 просто не сможет определить более точный тип из имени, которое не может разрешить статически.