Request
Djapy simplifies the process of handling request data and query parameters in your API. Here's how easily you can do it.
Data Input
You can use Schema
, Form
or TypedDict
to define the request data schema. Schema
is recommended, but feel free to play
around.
Schema
only accepts JSON data, with theContent-Type: application/json
header.Form
only accepts form data, with theContent-Type: application/x-www-form-urlencoded
header.TypedDict
only accepts JSON data, with theContent-Type: application/json
header.
Schema
Schema helps you to define the request data schema. It's a subclass of pydantic.BaseModel
that adds some extra
functionality.
# schemas.py
from djapy import Schema
class CreateUserSchema(Schema):
username: str
email: EmailStr
# views.py
@djapify(allowed_method=['POST'])
def create_user(request, data: CreateUserSchema) -> {...}:
user = User.objects.create_user(username=data.username, password=data.password)
return user
- The schema is used to validate the request data before it's passed to the view function.
- If the data is invalid, a pydantic error will be raised and returned as a response.
HTTP Request:
POST /create-user/ HTTP/1.1
Content-Type: application/json
{
"username": "bishwas",
"email": "[email protected]"
}
Query Parameters
You can also accept query parameters in your view function:
@djapify
def get_user(request, username: str) -> {200: UserSchema, 404: str}:
user = User.objects.get(username=username)
return user
HTTP Request:
Allowed query parameter types
These are the list of allowed query parameter types [basic parameters]
:
str
orOptional[str]
orLiteral["value1", "value2"]
int
orOptional[int]
orLiteral[1, 2, 3]
float
orOptional[float]
bool
datetime
constr()
orconint()
orconfloat()
orcondecimal()
- Iterable types:
list
,tuple
,set
;list[int]
,tuple[str]
, etc.
If anything other than these types are used, it will be considered as a data (payload) input.
Like:
Schema
orTypedDict
;
Invalid request error response
{
"error": [
{
"type": "missing",
"loc": [
"username"
],
"msg": "Field required",
"input": {
"my_id": "1",
"id": "1"
},
"url": "https://errors.pydantic.dev/2.6/v/missing"
},
{
"type": "missing",
"loc": [
"email"
],
"msg": "Field required",
"input": {
"my_id": "1",
"id": "1"
},
"url": "https://errors.pydantic.dev/2.6/v/missing"
}
],
"error_count": 2,
"title": "CreateUserSchema"
}
How-to
How to use basic parameters as data input?
You can use basic parameters as data input by using a payload
function:
from djapy.schema import payload
@djapify(allowed_method=['POST'])
def check_site_exists(request, url: payload(HttpUrl), check_all_pages: payload(bool) = False) -> bool:
if does_site_exist(url, check_all_pages):
return True
else:
return False
HTTP Request:
POST /check-site-exists/ HTTP/1.1
Content-Type: application/json
{
"url": "https://www.google.com",
"check_all_pages": true
}
Now, you can use the url
and check_all_pages
as data input. The url
will be validated as a HttpUrl
and check_all_pages
will be validated as a bool
.
How to use constr()
as data input?
You can use constr()
to validate a string, according to the constraints provided.
Visit Pydantic's constr for more information.
from pydantic import constr
@djapify
def search_game_by_name(request, name: constr(min_length=3, max_length=50)) -> {200: GameSchema, 404: str}:
game = Game.objects.get(name__icontains=name)
return game
- We set the minimum length of the
name
to 3 and the maximum length to 50. Validation will be done accordingly.
The similar goes for conint()
, confloat()
, or any other con*
Constraints.
If in schema: