@@ -115,7 +115,7 @@ TIP: If you're new to Python, you may never have seen the `with` statement.
115
115
It's used with what are called "context managers", which wrap a block of code,
116
116
usually with some kind of setup, cleanup, or error-handling code.
117
117
There's a good write-up in the
118
- http ://docs.python.org/release/2.5/whatsnew/pep-343.html[Python 2.5 release notes].
118
+ https ://docs.python.org/release/2.5/whatsnew/pep-343.html[Python 2.5 release notes].
119
119
((("with statements")))
120
120
((("Python 3", "with statements")))
121
121
@@ -151,10 +151,11 @@ A Django Quirk: Model Save Doesn't Run Validation
151
151
((("model-layer validation", "running full validation")))
152
152
And now we discover one of Django's little quirks.
153
153
_This test should already pass_.
154
- f you take a look at the
155
- http://bit.ly/SuxPJO[docs for the Django model fields],
156
- you'll see that `TextField` actually defaults to `blank=False`, which means
157
- that it 'should' disallow empty values.
154
+ If you take a look at the
155
+ https://docs.djangoproject.com/en/4.2/ref/models/fields/#blank[docs for the Django model fields],
156
+ you'll see under _Field options_ that the default setting for `blank` is `False`. Which means,
157
+ since TextField is a type of Field, it 'should' disallow empty values.
158
+ // CSANAD: I rephrased this a little, because `blank` is False for all `Field`s.
158
159
159
160
((("data integrity errors")))
160
161
So why is the test still failing?
@@ -187,7 +188,7 @@ No changes detected
187
188
((("full_clean method")))Django
188
189
does have a method to manually run full validation, however, called
189
190
`full_clean` (more info in
190
- http ://bit.ly/2u5SIxA [the docs]).
191
+ https ://docs.djangoproject.com/en/4.2/ref/models/instances/#django.db.models.Model.full_clean [the docs]).
191
192
Let's hack it in to see it work:
192
193
193
194
@@ -221,7 +222,7 @@ Surfacing Model Validation Errors in the View
221
222
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
222
223
223
224
((("model-layer validation", "surfacing errors in the view", id="MLVsurfac13")))
224
- Let" s try to enforce our model validation in the views layer
225
+ Let' s try to enforce our model validation in the views layer
225
226
and bring it up through into our templates, so the user can see them.
226
227
Here's how we can optionally display an error in our HTML--we check whether the template has
227
228
been passed an error variable, and if so, we do this:
@@ -251,8 +252,15 @@ been passed an error variable, and if so, we do this:
251
252
252
253
((("Bootstrap", "documentation")))
253
254
((("form control classes (Bootstrap)")))
254
- Take a look at the http ://getbootstrap.com/css/# forms[Bootstrap docs] for more
255
+ Take a look at the https ://getbootstrap.com/docs/5.3/ forms/validation/#server-side [Bootstrap docs] for more
255
256
info on form controls.
257
+ // CSANAD: these are the new docs for Bootstrap, but for some reason they begin
258
+ // with saying "We recommend client-side validation" which is bad.
259
+ // Client side validation is fine for faster UI aesthetics, sure. But they are
260
+ // not emphasizing that it is only for faster feedback and for security,
261
+ // whatever reaches the server should be validated on the server side before
262
+ // accepting it as an input for literally anything... Maybe we should mention
263
+ // this in a side note?
256
264
257
265
Passing this error to the template is the job of the view function. Let's take
258
266
a look at the unit tests in the `NewListTest` class. I'm going to use two
@@ -416,7 +424,7 @@ self.assertContains(response, expected_error)
416
424
====
417
425
418
426
...will show us the cause—Django has
419
- https://docs.djangoproject.com/en/1.11 /ref/templates/builtins/#autoescape[HTML-escaped]
427
+ https://docs.djangoproject.com/en/4.2 /ref/templates/builtins/#autoescape[HTML-escaped]
420
428
the apostrophe:
421
429
422
430
----
@@ -964,7 +972,7 @@ a [keep-together]#parameter#:
964
972
====
965
973
966
974
See the
967
- http ://bit.ly/2uKaMzA [Django
975
+ https ://docs.djangoproject.com/en/4.2/topics/http/urls/#reverse-resolution-of-urls [Django
968
976
docs on reverse URL resolution] for more info. We run the tests again, and check that they all pass:
969
977
970
978
[subs="specialcharacters,macros"]
@@ -1043,7 +1051,7 @@ AttributeError: 'List' object has no attribute 'get_absolute_url'
1043
1051
The implementation is to use Django's `reverse` function, which
1044
1052
essentially does the reverse of what Django normally does with 'urls.py'
1045
1053
(see the
1046
- https://docs.djangoproject.com/en/1.11 /topics/http/urls/#reverse-resolution-of-urls[docs]):
1054
+ https://docs.djangoproject.com/en/4.2 /topics/http/urls/#reverse-resolution-of-urls[docs]):
1047
1055
1048
1056
1049
1057
[role="sourcecode"]
@@ -1077,7 +1085,7 @@ def new_list(request):
1077
1085
====
1078
1086
1079
1087
There's more info in the
1080
- https://docs.djangoproject.com/en/1.11 /topics/http/shortcuts/#redirect[Django
1088
+ https://docs.djangoproject.com/en/4.2 /topics/http/shortcuts/#redirect[Django
1081
1089
docs]. Quick check that the unit tests still pass:
1082
1090
1083
1091
[subs="specialcharacters,macros"]
0 commit comments