Query parameters
When you declare other function parameters that are not part of the path parameters, they are automatically interpreted as "query" parameters.
weapons = ["Ninjato", "Shuriken", "Katana", "Kama", "Kunai", "Naginata", "Yari"]
@api.get("/weapons")
def list_weapons(request, limit: int = 10, offset: int = 0):
return weapons[offset: offset + limit]
To query this operation we would use url like
http://localhost:8000/api/weapons?offset=0&limit=10
By default all GET parameters are strings, and when you annotate your function arguments with types, they are converted to that type and validated against it.
All the same process that applied for path parameters also applies for query parameters:
- Editor support (obviously)
- Data "parsing"
- Data validation
- Automatic documentation
Note: if you do not annotate your arguments - it will be treated as str
types:
@api.get("/weapons")
def list_weapons(request, limit, offset):
# type(limit) == str
# type(offset) == str
Defaults
As query parameters are not a fixed part of a path, they can be optional and can have default values:
@api.get("/weapons")
def list_weapons(request, limit: int = 10, offset: int = 0):
return weapons[offset : offset + limit]
In the example above we set default values of offset=0
and limit=10
.
So, going to the URL:
http://localhost:8000/api/weapons
would be the same as going to:
http://localhost:8000/api/weapons?offset=0&limit=10
But if you go to, for example:
http://localhost:8000/api/weapons?offset=20
The parameter values in your function will be:
offset=20
: because you set it in the URLlimit=10
: because that was the default value
Required and optional parameters
You can declare required or optional GET parameters same way as you declare python function arguments:
weapons = ["Ninjato", "Shuriken", "Katana", "Kama", "Kunai", "Naginata", "Yari"]
@api.get("/weapons/search")
def search_weapons(request, q: str, offset: int = 0):
results = [w for w in weapons if q in w.lower()]
print(q, results)
return results[offset: offset + 10]
In this case Django Ninja will always validate that you pass q
param in GET, and offset
param is optional integer
GET parameters type conversion
Let's declare multiple type arguments:
from datetime import date
@api.get("/example")
def example(request, s: str = None, b: bool = None, d: date = None, i: int = None):
return [s, b, d, i]
The str
type is passed as is
For bool
type all of the following:s
http://localhost:8000/api/example?b=1
http://localhost:8000/api/example?b=True
http://localhost:8000/api/example?b=true
http://localhost:8000/api/example?b=on
http://localhost:8000/api/example?b=yes
or any other case variation (uppercase, first letter in uppercase, etc), your function will see the parameter b
with a bool
value of True
. Otherwise as False
.
Date can be both date string and integer (unix timestamp):
http://localhost:8000/api/example?d=1577836800 # = 2020-01-01 http://localhost:8000/api/example?d=2020-01-01
Using Schema
You can as well use Schema to encapsulate GET parameters:
import datetime
from ninja import Schema, Query
class Filters(Schema):
limit: int = 100
offset: int = None
query: str = None
@api.get("/filter")
def events(request, filters: Filters = Query(...)):
return {"filters": filters.dict()}