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
Parser for nested data for *multipart/form*, usable in any Python project or via the [Django Rest Framework integration](https://www.django-rest-framework.org/community/third-party-packages/#parsers)..
10
9
# Installation:
11
10
12
11
```bash
@@ -35,6 +34,16 @@ def my_view():
35
34
36
35
### Django Rest Framework
37
36
37
+
you can define parser for all view in settings.py
38
+
```python
39
+
REST_FRAMEWORK= {
40
+
"DEFAULT_PARSER_CLASSES": [
41
+
"nested_multipart_parser.drf.DrfNestedParser",
42
+
]
43
+
}
44
+
```
45
+
or directly in your view
46
+
38
47
```python
39
48
from nested_multipart_parser.drf import DrfNestedParser
40
49
...
@@ -46,7 +55,7 @@ class YourViewSet(viewsets.ViewSet):
46
55
47
56
## What it does:
48
57
49
-
The parser take the request data and transform it to a Python dictionary:
58
+
The parser takes the request data and transforms it into a Python dictionary.
50
59
51
60
example:
52
61
@@ -94,126 +103,106 @@ example:
94
103
}
95
104
```
96
105
97
-
## How it works:
98
-
99
-
Attributes where sub keys are full numbers only are automatically converted into lists:
106
+
## How it works
107
+
### Lists
100
108
109
+
Attributes whose sub‑keys are *only numbers* become Python lists:
101
110
```python
102
-
data = {
103
-
'title[0]': 'my-value',
104
-
'title[1]': 'my-second-value'
105
-
}
106
-
output = {
107
-
'title': [
108
-
'my-value',
109
-
'my-second-value'
110
-
]
111
-
}
112
-
113
-
# Be aware of the fact that you have to respect the order of the indices for arrays, thus
114
-
'title[2]': 'my-value'# Invalid (you have to set title[0] and title[1] before)
115
-
116
-
# Also, you can't create an array on a key already set as a prinitive value (int, boolean or string):
117
-
'title': 42,
118
-
'title[object]': 42# Invalid
111
+
data = {
112
+
'title[0]': 'my-value',
113
+
'title[1]': 'my-second-value'
114
+
}
115
+
output = {
116
+
'title': [
117
+
'my-value',
118
+
'my-second-value'
119
+
]
120
+
}
119
121
```
122
+
> Important notes
120
123
121
-
122
-
123
-
Attributes where sub keys are other than full numbers are converted into Python dictionary:
124
-
124
+
- Indices must be contiguous and start at 0.
125
+
- You cannot turn a primitive (int, bool, str) into a list later, e.g.
125
126
```python
126
-
data = {
127
-
'title.key0': 'my-value',
128
-
'title.key7': 'my-second-value'
129
-
}
130
-
output = {
131
-
'title': {
132
-
'key0': 'my-value',
133
-
'key7': 'my-second-value'
134
-
}
135
-
}
136
-
137
-
138
-
# You have no limit for chained key:
139
-
# with "mixed-dot" separator option (same as 'mixed' but with dot after list to object):
140
-
data = {
141
-
'the[0].chained.key[0].are.awesome[0][0]': 'im here !!'
142
-
}
143
-
# with "mixed" separator option:
144
-
data = {
145
-
'the[0]chained.key[0]are.awesome[0][0]': 'im here !!'
146
-
}
147
-
# With "bracket" separator option:
148
-
data = {
149
-
'the[0][chained][key][0][are][awesome][0][0]': 'im here !!'
150
-
}
151
-
# With "dot" separator option:
152
-
data = {
153
-
'the.0.chained.key.0.are.awesome.0.0': 'im here !!'
154
-
}
127
+
'title': 42,
128
+
'title[object]': 42# ❌ invalid
155
129
```
156
130
131
+
### Dictionaries
157
132
133
+
Attributes whose sub‑keys are *not pure numbers* become nested dictionaries:
134
+
```python
135
+
data = {
136
+
'title.key0': 'my-value',
137
+
'title.key7': 'my-second-value'
138
+
}
139
+
output = {
140
+
'title': {
141
+
'key0': 'my-value',
142
+
'key7': 'my-second-value'
143
+
}
144
+
}
145
+
```
158
146
159
-
For this to work perfectly, you must follow the following rules:
160
-
161
-
- A first key always need to be set. ex: `title[0]` or `title`. In both cases the first key is `title`
162
-
163
-
- For `mixed` or `mixed-dot` options, brackets `[]` is for list, and dot `.` is for object
147
+
### Chaining keys
164
148
165
-
- For `mixed-dot` options is look like `mixed` but with dot when object follow list
149
+
>Keys can be chained arbitrarily. Below are examples for each separator option:
166
150
167
-
- For `bracket` each sub key need to be separate by brackets `[ ]` or with `dot` options `.`
151
+
|Separator| Example key | Meaning|
152
+
|-|-|-|
153
+
|mixed‑dot| the[0].chained.key[0].are.awesome[0][0]|List → object → list → object …|
154
+
|mixed| the[0]chained.key[0]are.awesome[0][0]| Same as mixed‑dot but without the dot after a list|
155
+
|bracket| the[0][chained][key][0][are][awesome][0][0]| Every sub‑key is wrapped in brackets|
156
+
|dot |the.0.chained.key.0.are.awesome.0.0 | Dots separate every level; numeric parts become lists|
168
157
169
-
- For `bracket` or `dot`options, if a key is number is convert to list else a object
170
158
171
-
- Don't put spaces between separators.
159
+
Rules to keep in mind
160
+
- First key must exist – e.g. title[0] or just title.
161
+
- For mixed / mixed‑dot, [] denotes a list and . denotes an object.
162
+
- mixed‑dot behaves like mixed but inserts a dot when an object follows a list.
163
+
- For bracket, each sub‑key must be surrounded by brackets ([]).
164
+
- For bracket or dot, numeric sub‑keys become list elements; non‑numeric become objects.
165
+
- No spaces between separators.
166
+
- By default, duplicate keys are disallowed (see options).
167
+
- Empty structures are supported:
168
+
Empty list → "article.authors[]": None → {"article": {"authors": []}}
@@ -223,20 +212,20 @@ For this to work perfectly, you must follow the following rules:
223
212
# settings.py
224
213
...
225
214
215
+
# settings.py
226
216
DRF_NESTED_MULTIPART_PARSER= {
227
-
"separator": "mixed-dot",
228
-
"raise_duplicate": True,
229
-
"assign_duplicate": False,
217
+
"separator": "mixed‑dot",
218
+
"raise_duplicate": True,
219
+
"assign_duplicate": False,
230
220
231
-
# output of parseris converted to querydict
232
-
# if is set to False, dict python is returned
233
-
"querydict": True,
221
+
# If True, the parser’s output is converted to a QueryDict;
222
+
# if False, a plain Python dict is returned.
223
+
"querydict": True,
234
224
}
235
225
```
236
226
237
227
## JavaScript integration:
238
-
239
-
You can use this [multipart-object](https://github.com/remigermain/multipart-object) library to easy convert object to flat nested object formatted for this library
228
+
A companion [multipart-object](https://github.com/remigermain/multipart-object) library exists to convert a JavaScript object into the flat, nested format expected by this parser.
0 commit comments