Источники данных¶
При вызове MySchema(request) django-pydantic-client строит плоский dict, объединяя данные из нескольких источников. Эта страница объясняет, что именно объединяется и в каком порядке.
Порядок слияния¶
Источники объединяются слева направо. Более поздние источники перекрывают более ранние.
| Источник | Когда используется | Пример |
|---|---|---|
request.GET |
Всегда | ?page=2&sort=name |
request.POST |
Не GET/HEAD/DELETE, не JSON | Отправка HTML-формы |
| JSON тело | Content-Type: application/json |
REST API клиенты |
| URL kwargs | При явной передаче | MySchema(request, pk=pk) |
Note
POST-данные формы и JSON-тело взаимоисключающие — используется только один
источник в зависимости от заголовка Content-Type.
GET-параметры запроса¶
Включаются всегда, независимо от HTTP-метода:
data = SearchSchema(request)
# data.q == "python"
# data.page == 2
# data.page_size == 20 (по умолчанию)
Приведение типов
Параметры запроса приходят как строки. Pydantic автоматически приводит их
к объявленному типу — "2" становится int(2), "true" становится True.
JSON-тело¶
Используется, когда запрос содержит Content-Type: application/json:
curl -X POST /users/ \
-H "Content-Type: application/json" \
-d '{"username": "alice", "email": "alice@example.com"}'
data = CreateUserSchema(request)
# data.username == "alice"
# data.email == "alice@example.com"
# data.is_admin == False
POST-данные формы¶
Используются при стандартной отправке HTML-формы (application/x-www-form-urlencoded или multipart/form-data):
<form method="POST" action="/contact/">
<input name="name" type="text">
<input name="email" type="email">
<textarea name="message"></textarea>
</form>
class ContactSchema(RequestModel):
name: str
email: EmailStr
message: str = Field(min_length=10)
def contact(request):
if request.method == "POST":
data = ContactSchema(request)
# отправить email...
Смешивание GET + тело¶
GET-параметры и данные тела объединяются. Удобно для фильтрующих эндпоинтов, которые принимают пагинацию через URL и критерии фильтрации через тело:
class ProductFilterSchema(RequestModel):
page: int = 1 # из GET: /products/?page=3
category: str = "" # из JSON или GET
min_price: float = 0
max_price: float = 99999
data = ProductFilterSchema(request)
# data.page == 3 (из GET)
# data.category == "electronics" (из JSON)
# data.min_price == 100.0
Параметры URL-пути¶
URL-kwargs имеют наивысший приоритет. Передавай их явно:
# urls.py
path("users/<int:pk>/", user_detail)
# views.py
def user_detail(request, pk):
data = UserDetailSchema(request, pk=pk) # (1)!
pkобъединяется в словарь данных с наивысшим приоритетом, перекрывая любойpkв query string или теле.
Подробнее: Параметры URL.
Пример приоритета¶
Если один ключ встречается в нескольких источниках, побеждает источник с наивысшим приоритетом:
class ItemSchema(RequestModel):
id: int
# Вызов: ItemSchema(request)
# GET говорит id=1, JSON говорит id=2 → тело выигрывает → data.id == 2
# Вызов: ItemSchema(request, id=99)
# URL kwarg выигрывает → data.id == 99
Далее: Ошибки валидации →