Skip to content

Commit 15ea2c9

Browse files
Serbel97Sibyx
andauthored
Ignore default clean method if error exists (#60) 🧕🏽
* Ignore default clean method if error exists * updated documentation * Dependencies 🫒 * Removed 3.8 python version from tests --------- Co-authored-by: Jakub Dubec <[email protected]>
1 parent 0af6aba commit 15ea2c9

File tree

5 files changed

+81
-21
lines changed

5 files changed

+81
-21
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 1.0.0-rc.8 : 07.03.2023
4+
5+
- **Changed**: Default clean method `Form.clean` is only called when there are no errors.
6+
37
## 1.0.0-rc.7 : 24.11.2022
48

59
CI/CD fixies and project settings. There was no application change.

django_api_forms/forms.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,12 @@ def full_clean(self):
142142
self.add_error((key, ), e)
143143
except (AttributeError, TypeError, ValueError):
144144
self.add_error((key, ), ValidationError(_("Invalid value")))
145-
try:
146-
cleaned_data = self.clean()
147-
except ValidationError as e:
148-
self.add_error(('$body', ), e)
149-
else:
150-
if cleaned_data is not None:
151-
self.cleaned_data = cleaned_data
145+
146+
if not self._errors:
147+
try:
148+
self.cleaned_data = self.clean()
149+
except ValidationError as e:
150+
self.add_error(('$body',), e)
152151

153152
def clean(self):
154153
"""

docs/tutorial.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ This process is much more simple than in classic Django form. It consists of:
8484
- calling `Form.add_error((field_name, ), error)` in case of failures in clean methods
8585
- if field is marked as dirty, normalized attribute is saved to `Form.clean_data` property
8686
2. Calling `Form.clean` method which returns final normalized values which will be presented in `Form.clean_data`
87-
(feel free to override it, by default does nothing, useful for conditional validation, you can still add errors u
88-
sing `Form.add_error()`)
87+
(feel free to override it, by default does nothing, useful for conditional validation, you can still add errors
88+
using `Form.add_error()`). `Form.clean` is only called when there are no errors from previous section.
8989

9090
Normalized data are available in `Form.clean_data` property (keys suppose to correspond with values from `Form.dirty`).
9191

tests/test_nested_forms.py

-5
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,6 @@ def test_invalid(self):
5555
"message": "Enter a valid date/time.",
5656
"path": ["bands", 1, "albums", 0, "metadata", "error_at"]
5757
},
58-
{
59-
"code": "time-traveling",
60-
"message": "Sounds like a bullshit",
61-
"path": ["bands", 1, "albums", 0, "$body"]
62-
},
6358
{
6459
"code": "invalid",
6560
"message": "Enter a valid email address.",

tests/test_validation.py

+69-7
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,6 @@ def test_invalid(self):
4747
"metadata",
4848
"error_at"
4949
]
50-
},
51-
{
52-
"code": "time-traveling",
53-
"message": "Sounds like a bullshit",
54-
"path": [
55-
"$body"
56-
]
5750
}
5851
]
5952
}
@@ -119,3 +112,72 @@ def test_valid(self):
119112

120113
self.assertTrue(form.is_valid())
121114
self.assertEqual(form.cleaned_data, expected)
115+
116+
def test_default_clean(self):
117+
data = {
118+
"title": "Unknown Pleasures",
119+
"type": "vinyl",
120+
"artist": {
121+
"name": "Joy Division",
122+
"genres": [
123+
"rock",
124+
"punk"
125+
],
126+
"members": 4
127+
},
128+
"year": 1998,
129+
"songs": [
130+
{
131+
"title": "Disorder",
132+
"duration": "3:29"
133+
},
134+
{
135+
"title": "Day of the Lords",
136+
"duration": "4:48",
137+
"metadata": {
138+
"_section": {
139+
"type": "ID3v2",
140+
"offset": 0,
141+
"byteLength": 2048
142+
},
143+
"header": {
144+
"majorVersion": 3,
145+
"minorRevision": 0,
146+
"flagsOctet": 0,
147+
"unsynchronisationFlag": False,
148+
"extendedHeaderFlag": False,
149+
"experimentalIndicatorFlag": False,
150+
"size": 2038
151+
}
152+
}
153+
}
154+
],
155+
"metadata": {
156+
"created_at": "2019-10-21T18:57:03+0100",
157+
"updated_at": "2019-10-21T18:57:03+0100"
158+
}
159+
}
160+
161+
rf = RequestFactory()
162+
163+
expected = {
164+
"errors": [
165+
{
166+
"code": "time-traveling",
167+
"message": "Sounds like a bullshit",
168+
"path": [
169+
"$body"
170+
]
171+
}
172+
]
173+
}
174+
175+
request = rf.post('/foo/bar', data=data, content_type='application/json')
176+
177+
form = AlbumForm.create_from_request(request)
178+
179+
self.assertFalse(form.is_valid())
180+
error = {
181+
'errors': [item.to_dict() for item in form._errors]
182+
}
183+
self.assertEqual(error, expected)

0 commit comments

Comments
 (0)