Path parameters
You can declare path "parameters" with the same syntax used by Python format-strings (which luckily also matches the OpenAPI path parameters):
@api.get("/items/{item_id}")
def read_item(request, item_id):
return {"item_id": item_id}
The value of the path parameter item_id
will be passed to your function as the argument item_id
.
So, if you run this example and go to http://localhost:8000/api/items/foo, you will see this response:
{"item_id":"foo"}
Path parameters with types
You can declare the type of path parameter in the function using standard Python type annotations:
@api.get("/items/{item_id}")
def read_item(request, item_id: int):
return {"item_id": item_id}
In this case,item_id
is declared to be an int
. This will give you editor and linter support for error checks, completion, etc.
If you run this in your browser with http://localhost:8000/api/items/3, you will see this response:
{"item_id":3}
Tip
Notice that the value your function received (and returned) is 3, as a Python int
- not a string "3"
.
So, with just that type declaration, Django Ninja gives you automatic request "parsing" and validation.
Data validation
On the other hand, if you go to the browser at http://localhost:8000/api/items/foo ("foo"
is not int), you will see an HTTP error like this:
{
"detail": [
{
"loc": [
"path",
"item_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
Django Path Converters
You can use Django Path Converters to help parse the path:
@api.get("/items/{int:item_id}")
def read_item(request, item_id):
return {"item_id": item_id}
In this case,item_id
will be parsed as an int
. If item_id
is not a valid int
, the url will not
match. (e.g. if no other path matches, a 404 Not Found will be returned)
Tip
Notice that, since Django Ninja uses a default type of str
for unannotated parameters, the value the
function above received (and returned) is "3"
, as a Python str
- not an integer 3. To receive
an int
, simply declare item_id
as an int
type annotation in the function definition as normal:
@api.get("/items/{int:item_id}")
def read_item(request, item_id:int):
return {"item_id": item_id}
Path params with slashes
Django's path
converter allows you to handle path-like parameters:
@api.get('/dir/{path:value}')
def someview(request, value: str):
return value
/dir/some/path/with-slashes
and your value
will be equal to some/path/with-slashes
Multiple parameters
You can pass as many variables as you want into path
, just remember to have unique names and don't forget to use the same names in the function arguments.
@api.get("/events/{year}/{month}/{day}")
def events(request, year: int, month: int, day: int):
return {"date": [year, month, day]}
Using Schema
You can also use Schema to encapsulate path parameters that depend on each other (and validate them as a group):
import datetime
from ninja import Schema, Path
class PathDate(Schema):
year: int
month: int
day: int
def value(self):
return datetime.date(self.year, self.month, self.day)
@api.get("/events/{year}/{month}/{day}")
def events(request, date: Path[PathDate]):
return {"date": date.value()}
Note
Notice that here we used a Path
source hint to let Django Ninja know that this schema will be applied to path parameters.
Documentation
Now, when you open your browser at http://localhost:8000/api/docs, you will see the automatic, interactive, API documentation.