You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Request bodies are typically used with “create” and “update” operations (POST, PUT, PATCH).
4
4
For example, when creating a resource using POST or PUT, the request body usually contains the representation of the resource to be created.
5
5
6
-
To declare a **request body**, you need to use **Django Ninja `Schema`**.
6
+
To declare a **request body**, you need to use **Ellar `Serializer`**.
7
7
8
8
!!! info
9
-
Under the hood **Django Ninja** uses <ahref="https://pydantic-docs.helpmanual.io/"class="external-link"target="_blank">Pydantic</a> models with all their power and benefits.
10
-
The alias `Schema` was chosen to avoid confusion in code when using Django models, as Pydantic's model class is called Model by default, and conflicts with Django's Model class.
9
+
Under the hood **Ellar** uses <ahref="https://pydantic-docs.helpmanual.io/"class="external-link"target="_blank">Pydantic</a> models with all their power and benefits.
11
10
12
-
## Import Schema
11
+
## Import Serializer
13
12
14
-
First, you need to import `Schema` from `ninja`:
13
+
First, you need to import `Serializer` from `ella.serializer`:
14
+
15
+
```python
16
+
# project_name/apps/items/controllers.py
17
+
from ellar.serializer import Serializer
18
+
19
+
# class Item(Serializer):
20
+
# name: str
21
+
# description: str = None
22
+
# price: float
23
+
# quantity: int
15
24
16
-
```Python hl_lines="1"
17
-
{!./src/tutorial/body/code01.py!}
18
25
```
19
26
20
27
## Create your data model
21
28
22
-
Then you declare your data model as a class that inherits from `Schema`.
29
+
Then you declare your data model as a class that inherits from `Serializer`.
23
30
24
31
Use standard Python types for all the attributes:
25
32
26
-
```Python hl_lines="4 5 6 7 8"
27
-
{!./src/tutorial/body/code01.py!}
33
+
```python
34
+
# project_name/apps/items/controllers.py
35
+
36
+
from ellar.serializer import Serializer
37
+
from ellar.common import Controller, post
38
+
from ellar.core import ControllerBase
39
+
40
+
41
+
classItem(Serializer):
42
+
name: str
43
+
description: str=None
44
+
price: float
45
+
quantity: int
46
+
47
+
48
+
@Controller
49
+
classItemsController(ControllerBase):
50
+
@post("/")
51
+
defcreate(self, item: Item):
52
+
return item
28
53
```
29
54
30
55
Note: if you use **`None`** as the default value for an attribute, it will become optional in the request body.
31
56
For example, this model above declares a JSON "`object`" (or Python `dict`) like:
32
57
33
58
```JSON
34
59
{
35
-
"name": "Katana",
60
+
"name": "Alexis",
36
61
"description": "An optional description",
37
-
"price": 299.00,
38
-
"quantity": 10
62
+
"price": 400.00,
63
+
"quantity": 6
39
64
}
40
65
```
41
66
42
67
...as `description` is optional (with a default value of `None`), this JSON "`object`" would also be valid:
43
68
44
69
```JSON
45
70
{
46
-
"name": "Katana",
47
-
"price": 299.00,
48
-
"quantity": 10
71
+
"name": "Alexis",
72
+
"price": 200.00,
73
+
"quantity": 12
49
74
}
50
75
```
51
76
52
77
## Declare it as a parameter
53
78
54
79
To add it to your *path operation*, declare it the same way you declared the path and query parameters:
55
80
56
-
```Python hl_lines="12"
57
-
{!./src/tutorial/body/code01.py!}
81
+
```python
82
+
# project_name/apps/items/controllers.py
83
+
84
+
from ellar.serializer import Serializer
85
+
from ellar.common import Controller, post
86
+
from ellar.core import ControllerBase
87
+
88
+
89
+
classItem(Serializer):
90
+
name: str
91
+
description: str=None
92
+
price: float
93
+
quantity: int
94
+
95
+
96
+
@Controller
97
+
classItemsController(ControllerBase):
98
+
@post("/")
99
+
defcreate(self, item: Item):
100
+
return item
58
101
```
59
102
60
103
... and declare its type as the model you created, `Item`.
61
104
62
105
## Results
63
106
64
-
With just that Python type declaration, **Django Ninja** will:
107
+
With just that Python type declaration, **Ellar** will:
65
108
66
109
* Read the body of the request as JSON.
67
110
* Convert the corresponding types (if needed).
@@ -74,7 +117,7 @@ With just that Python type declaration, **Django Ninja** will:
74
117
your models, and you can also use them anywhere else you like if it makes sense for your project.
75
118
* Those schemas will be part of the generated OpenAPI schema, and used by the automatic documentation <abbrtitle="User Interfaces">UI's</abbr>.
76
119
77
-
## Automatic docs
120
+
## Automatic Docs
78
121
79
122
The JSON Schemas of your models will be part of your OpenAPI generated schema, and will be shown in the interactive API docs:
80
123
@@ -84,40 +127,189 @@ The JSON Schemas of your models will be part of your OpenAPI generated schema, a
84
127
85
128

86
129
87
-
## Editor support
88
-
89
-
In your editor, inside your function you will get type hints and completion everywhere (this wouldn't happen if you received a `dict` instead of a Schema object):
90
-
91
-

92
130
131
+
## Request Body + Path parameters
93
132
94
-
The previous screenshots were taken with <ahref="https://code.visualstudio.com"class="external-link"target="_blank">Visual Studio Code</a>.
133
+
You can declare path parameters **and** body requests at the same time.
95
134
96
-
You would get the same editor support with <ahref="https://www.jetbrains.com/pycharm/"class="external-link"target="_blank">PyCharm</a> and most of the other Python editors.
135
+
**Ellar** will recognize that the function parameters that match path parameters should be **taken from the path**, and that function parameters that are declared with `Serializer` should be **taken from the request body**.
97
136
137
+
```python
138
+
# project_name/apps/items/controllers.py
98
139
99
-
## Request body + path parameters
140
+
from ellar.serializer import Serializer
141
+
from ellar.common import Controller, post, put
142
+
from ellar.core import ControllerBase
100
143
101
-
You can declare path parameters **and** body requests at the same time.
102
144
103
-
**Django Ninja** will recognize that the function parameters that match path parameters should be **taken from the path**, and that function parameters that are declared with `Schema` should be **taken from the request body**.
145
+
classItem(Serializer):
146
+
name: str
147
+
description: str=None
148
+
price: float
149
+
quantity: int
104
150
105
-
```Python hl_lines="11 12"
106
-
{!./src/tutorial/body/code02.py!}
151
+
@Controller
152
+
classItemsController(ControllerBase):
153
+
@post("/")
154
+
defcreate(self, item: Item):
155
+
return item
156
+
157
+
@put("/items/{item_id}")
158
+
defupdate(self, item_id: int, item: Item):
159
+
return {"item_id": item_id, "item": item.dict()}
107
160
```
108
161
109
-
## Request body + path + query parameters
162
+
## Request Body + Path + Query parameters
110
163
111
164
You can also declare **body**, **path** and **query** parameters, all at the same time.
112
165
113
-
**Django Ninja** will recognize each of them and take the data from the correct place.
166
+
**Ellar** will recognize each of them and take the data from the correct place.
The function parameters will be recognized as follows:
120
194
121
195
* If the parameter is also declared in the **path**, it will be used as a path parameter.
122
196
* If the parameter is of a **singular type** (like `int`, `float`, `str`, `bool`, etc.), it will be interpreted as a **query** parameter.
123
-
* If the parameter is declared to be of the type of **Schema** (or Pydantic `BaseModel`), it will be interpreted as a request **body**.
197
+
* If the parameter is declared to be of the type of **Serializer** (or Pydantic `BaseModel`), it will be interpreted as a request **body**.
198
+
199
+
!!! info
200
+
In here, we have combined both `Serializers` and `Controllers` in one file. This is for the convenience of writing this documentation.
201
+
It's advised to have all your serializers in `schemas.py` and then import them over to `controllers.py` if needed.
202
+
203
+
## Singular values in body
204
+
The same way there is a `Query` and `Path` to define extra data for query and path parameters,
205
+
**Ellar** provides an equivalent `Body`.
206
+
207
+
For example, extending the previous model, you could decide that you want to have another key `importance` in the same body, besides the `item` and `user`.
208
+
209
+
If you declare it as is, because it is a singular value, **Ellar** will assume that it is a query parameter.
210
+
211
+
But you can instruct **Ellar** to treat it as another body key using Body:
212
+
213
+
```python
214
+
# project_name/apps/items/controllers.py
215
+
216
+
from ellar.serializer import Serializer
217
+
from ellar.common import Controller, Body, post, put
0 commit comments