2
2
3
3
When you declare other function parameters that are not part of the path parameters, they are automatically interpreted as "query" parameters.
4
4
5
- ``` Python hl_lines="5"
6
- {!./ src/ tutorial/ query/ code01.py!}
5
+ ``` python
6
+ from ellar.common import get, Controller
7
+ from ellar.core import ControllerBase
8
+
9
+ fake_items_db = [{" item_name" : " Foo" }, {" item_name" : " Bar" }, {" item_name" : " Baz" }]
10
+
11
+
12
+ @Controller
13
+ class ItemsController (ControllerBase ):
14
+ @get (' /weapons' )
15
+ def list_weapons (self , limit : int = 10 , offset : int = 0 ):
16
+ return fake_items_db[offset: offset + limit]
7
17
```
8
18
9
19
To query this operation, you use a URL like:
@@ -23,36 +33,53 @@ The same benefits that apply to path parameters also apply to query parameters:
23
33
24
34
Note: if you do not annotate your arguments, they will be treated as ` str ` types:
25
35
26
- ``` Python hl_lines="2"
27
- @api.get (" /weapons" )
28
- def list_weapons (request , limit , offset ):
29
- # type(limit) == str
30
- # type(offset) == str
36
+ ``` python
37
+ from ellar.common import get, Controller
38
+ from ellar.core import ControllerBase
39
+
40
+ fake_items_db = [{" item_name" : " Foo" }, {" item_name" : " Bar" }, {" item_name" : " Baz" }]
41
+
42
+
43
+ @Controller
44
+ class ItemsController (ControllerBase ):
45
+ @get (' /weapons' )
46
+ def list_weapons (self , limit , offset ):
47
+ assert type (limit) == str
48
+ assert type (offset) == str
49
+ return fake_items_db[offset: int (offset) + int (limit)]
31
50
```
32
51
33
52
### Defaults
34
53
35
54
As query parameters are not a fixed part of a path, they are optional and can have default values:
36
55
37
- ``` Python hl_lines="2"
38
- @api.get (" /weapons" )
39
- def list_weapons (request , limit : int = 10 , offset : int = 0 ):
40
- return weapons[offset : offset + limit]
56
+ ``` python
57
+ from ellar.common import get, Controller
58
+ from ellar.core import ControllerBase
59
+
60
+ fake_items_db = [{" item_name" : " Foo" }, {" item_name" : " Bar" }, {" item_name" : " Baz" }]
61
+
62
+
63
+ @Controller
64
+ class ItemsController (ControllerBase ):
65
+ @get (' /weapons' )
66
+ def list_weapons (self , limit : int = 10 , offset : int = 0 ):
67
+ return fake_items_db[offset: offset + limit]
41
68
```
42
69
43
70
In the example above we set default values of ` offset=0 ` and ` limit=10 ` .
44
71
45
72
So, going to the URL:
46
73
```
47
- http://localhost:8000/api /weapons
74
+ http://localhost:8000/items /weapons
48
75
```
49
76
would be the same as going to:
50
77
```
51
- http://localhost:8000/api /weapons?offset=0&limit=10
78
+ http://localhost:8000/items /weapons?offset=0&limit=10
52
79
```
53
80
If you go to, for example:
54
81
```
55
- http://localhost:8000/api /weapons?offset=20
82
+ http://localhost:8000/items /weapons?offset=20
56
83
```
57
84
58
85
the parameter values in your function will be:
@@ -65,43 +92,84 @@ the parameter values in your function will be:
65
92
66
93
You can declare required or optional GET parameters in the same way as declaring Python function arguments:
67
94
68
- ``` Python hl_lines="5"
69
- {!./ src/ tutorial/ query/ code02.py!}
95
+ ``` python
96
+ from ellar.common import get, Controller
97
+ from ellar.core import ControllerBase
98
+
99
+ weapons = [" Ninjato" , " Shuriken" , " Katana" , " Kama" , " Kunai" , " Naginata" , " Yari" ]
100
+
101
+
102
+ @Controller
103
+ class ItemsController (ControllerBase ):
104
+ @get (" /weapons/search" )
105
+ def search_weapons (self , q : str , offset : int = 0 ):
106
+ results = [w for w in weapons if q in w.lower()]
107
+ print (q, results)
108
+ return results[offset: offset + 10 ]
70
109
```
71
110
72
- In this case, ** Django Ninja ** will always validate that you pass the ` q ` param in the GET, and the ` offset ` param is an optional integer.
111
+ In this case, ** Ellar ** will always validate that you pass the ` q ` param in the GET, and the ` offset ` param is an optional integer.
73
112
74
113
### GET parameters type conversion
75
114
76
115
Let's declare multiple type arguments:
77
- ``` Python hl_lines="5"
78
- {!./ src/ tutorial/ query/ code03.py!}
116
+ ``` python
117
+ from ellar.common import get, Controller
118
+ from ellar.core import ControllerBase
119
+ from datetime import date
120
+
121
+
122
+ @Controller
123
+ class ItemsController (ControllerBase ):
124
+ @get (" /example" )
125
+ def example (self , s : str = None , b : bool = None , d : date = None , i : int = None ):
126
+ return [s, b, d, i]
79
127
```
80
128
The ` str ` type is passed as is.
81
129
82
130
For the ` bool ` type, all the following:
83
131
```
84
- http://localhost:8000/api /example?b=1
85
- http://localhost:8000/api /example?b=True
86
- http://localhost:8000/api /example?b=true
87
- http://localhost:8000/api /example?b=on
88
- http://localhost:8000/api /example?b=yes
132
+ http://localhost:8000/items /example?b=1
133
+ http://localhost:8000/items /example?b=True
134
+ http://localhost:8000/items /example?b=true
135
+ http://localhost:8000/items /example?b=on
136
+ http://localhost:8000/items /example?b=yes
89
137
```
90
138
or any other case variation (uppercase, first letter in uppercase, etc.), your function will see
91
139
the parameter ` b ` with a ` bool ` value of ` True ` , otherwise as ` False ` .
92
140
93
141
Date can be both date string and integer (unix timestamp):
142
+ ```
143
+ http://localhost:8000/items/example?d=1672286800
144
+ # same as 2022-12-29
94
145
95
- <pre style =" font-size : .85em ; background-color :rgb (245 , 245 , 245 );" >
96
- http://localhost:8000/api/example?d=<strong >1577836800</strong > # same as 2020-01-01
97
- http://localhost:8000/api/example?d=<strong >2020-01-01</strong >
98
- </pre >
99
-
146
+ http://localhost:8000/items/example?d=2022-12-29
147
+ ```
100
148
101
149
### Using Schema
102
150
103
151
You can also use Schema to encapsulate GET parameters:
104
152
105
- ``` Python hl_lines="1 2 5 6 7 8"
106
- {!./ src/ tutorial/ query/ code010.py!}
153
+ ``` python
154
+ from typing import List
155
+ from pydantic import Field
156
+ from ellar.serializer import Serializer
157
+ from ellar.common import get, Controller, Query
158
+ from ellar.core import ControllerBase
159
+
160
+
161
+
162
+ class Filters (Serializer ):
163
+ limit: int = 100
164
+ offset: int = None
165
+ query: str = None
166
+ category__in: List[str ] = Field(None , alias = " categories" )
167
+
168
+
169
+ @Controller
170
+ class ItemsController (ControllerBase ):
171
+ @get (' /query-as-schema' )
172
+ def query_as_schema (self , filters : Filters = Query()):
173
+ return {" filters" : filters.dict()}
107
174
```
175
+ ![ Query Doc] ( ../../img/query_filter_swagger.png )
0 commit comments