Skip to content

Commit eec12a3

Browse files
Restructured book, added Django chapter
1 parent 218fadb commit eec12a3

File tree

73 files changed

+869
-36
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+869
-36
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This is an open-source book of **Python anti-patterns and worst practices**. Che
55
**Notice**: This is still (and will always be) a work-in-progress, feel free to contribute by suggesting improvements, adding new articles, improving existing ones, or translating this into other languages.
66

77
# New articles
8-
If you add new articles, please use the provided [template](docs/template.rst).
8+
If you add new articles, please use the provided templates. Depending on the pattern you are creating, use either the [anti-pattern](templates/anti_pattern.rst) or the [migration-pattern](templates/migration_pattern.rst) template.
99

1010
#License
1111

docs/_themes/quantifiedcode/layout.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090

9191

9292
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
93-
{% set toctree = toctree(maxdepth=2, collapse=False, includehidden=True) %}
93+
{% set toctree = toctree(maxdepth=4, titles_only=True, collapse=True, includehidden=True) %}
9494
{% if toctree %}
9595
{{ toctree }}
9696
{% else %}
@@ -183,12 +183,12 @@
183183
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
184184
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
185185
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
186-
186+
187187
ga('create', 'UA-51790189-2', 'auto');
188188
ga('set', 'anonymizeIp', true);
189189
ga('send', 'pageview', {
190190
'page': location.pathname + location.search + location.hash
191-
});
191+
});
192192
</script>
193193

194194
{%- block footer %} {% endblock %}

docs/django/1.8/index.rst

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Django 1.8
2+
==========
3+
4+
In this section, you'll find anti-patterns that apply specifically to Django 1.8.
5+
6+
.. toctree::
7+
:maxdepth: 2
8+
9+
migration/index
10+

docs/django/1.8/migration/index.rst

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
:fa:`magic` Migration
2+
======================
3+
4+
Migrating to a new Django version can be time consuming. To make this process easier, this chapter lists deprecated features and shows potential migration patterns/pathes.
5+
6+
.. toctree::
7+
:maxdepth: 1
8+
9+
template_dirs_deprecated
10+
template_debug_deprecated
11+
template_loaders_deprecated
12+
template_string_if_invalid_deprecated
13+
14+
15+
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
``TEMPLATE_DEBUG`` deprecated
2+
=============================
3+
4+
This setting sets the output that the template system should use for invalid (e.g. misspelled) variables. The default value is an empty string ``''``. This setting is deprecated since Django version 1.8. Set the `TEMPLATE_DEBUG` option in the ``OPTIONS`` of a ``DjangoTemplates`` backend instead.
5+
6+
Deprecated feature
7+
------------------
8+
9+
Deprecated ``TEMPLATE_DEBUG`` setting used.
10+
11+
.. code:: python
12+
13+
""" settings.py """
14+
15+
TEMPLATE_DEBUG = True
16+
17+
18+
Migration path
19+
--------------
20+
21+
As of Django 1.8 you should set ``debug`` option in the ``OPTIONS`` of a ``DjangoTemplates`` backend instead.
22+
23+
.. code:: python
24+
25+
""" settings.py """
26+
27+
TEMPLATES = [
28+
{
29+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
30+
'APP_DIRS': True,
31+
'DIRS': '/path/to/my/templates',
32+
'OPTIONS': {
33+
'debug': True,
34+
}
35+
},
36+
]
37+
38+
References
39+
----------
40+
41+
- [Django documentation - Settings: TEMPLATE_DEBUG](https://docs.djangoproject.com/en/1.8/ref/settings/#template-debug)
42+
- [Django documentation - Settings: TEMPLATES](https://docs.djangoproject.com/en/1.8/ref/settings/#templates)
43+
- [Django documentation - Templates: Built-in backends](https://docs.djangoproject.com/en/1.8/topics/templates/#module-django.template.backends.django)
44+
45+
Status
46+
------
47+
48+
- `Automated code check available <https://www.quantifiedcode.com/app/pattern/705f569e1a174f39946454933994e4b3>`_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
``TEMPLATE_DIRS`` deprecated
2+
============================
3+
4+
This setting is deprecated since Django version 1.8. Set the ``DIRS`` option of a [`DjangoTemplates` backend](https://docs.djangoproject.com/en/1.8/topics/templates/#module-django.template.backends.django) instead.
5+
6+
Deprecated feature
7+
------------------
8+
9+
Deprecated ``TEMPLATE_DIRS`` setting used.
10+
11+
.. code:: python
12+
13+
""" settings.py """
14+
15+
TEMPLATE_DIRS = [
16+
"path/to/my/templates",
17+
]
18+
19+
Migration path
20+
--------------
21+
22+
As of Django 1.8 you should set ``DIRS`` option within ``TEMPLATES`` setting. It defines where the engine should look for template source files, in search order.
23+
24+
.. code:: python
25+
26+
""" settings.py """
27+
28+
TEMPLATES = [
29+
{
30+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
31+
'APP_DIRS': True,
32+
'DIRS': '/path/to/my/templates',
33+
},
34+
]
35+
36+
37+
References
38+
----------
39+
40+
- [Django documentation - Settings: TEMPLATES](https://docs.djangoproject.com/en/1.8/ref/settings/#templates)
41+
- [Django documentation - Settings: TEMPLATE_DIRS](https://docs.djangoproject.com/en/1.8/ref/settings/#template-dirs)
42+
- [Django documentation - Templates: Built-in backends](https://docs.djangoproject.com/en/1.8/topics/templates/#module-django.template.backends.django)
43+
44+
45+
Status
46+
------
47+
48+
- `Automated code check available <https://www.quantifiedcode.com/app/pattern/4af01dfd013241f58d0469e014209e3a>`_
49+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
``TEMPLATE_LOADERS`` deprecated
2+
===============================
3+
4+
This setting is deprecated since Django version 1.8. Set the `LOADERS` option of a [`DjangoTemplates` backend](https://docs.djangoproject.com/en/1.8/topics/templates/#module-django.template.backends.django) instead.
5+
6+
Deprecated feature
7+
------------------
8+
9+
Deprecated ``TEMPLATE_LOADERS`` setting used.
10+
11+
.. code:: python
12+
13+
""" settings.py """
14+
15+
TEMPLATE_LOADERS = (
16+
'django.template.loaders.filesystem.Loader',
17+
'django.template.loaders.app_directories.Loader',
18+
)
19+
```
20+
21+
Migration path
22+
--------------
23+
24+
As of Django 1.8 you should set ``loaders`` option in the ``TEMPLATES`` setting. It defines where the engine should look for template source files, in search order.
25+
26+
.. code:: python
27+
28+
""" settings.py """
29+
30+
TEMPLATES = [
31+
{
32+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
33+
'APP_DIRS': True,
34+
'DIRS': '/path/to/my/templates',
35+
'OPTIONS': {
36+
'loaders': (
37+
'django.template.loaders.filesystem.Loader',
38+
'django.template.loaders.app_directories.Loader',
39+
),
40+
}
41+
},
42+
]
43+
44+
45+
References
46+
----------
47+
48+
- [Django documentation - Settings: TEMPLATES](https://docs.djangoproject.com/en/1.8/ref/settings/#templates)
49+
- [Django documentation - Settings: TEMPLATE_DIRS](https://docs.djangoproject.com/en/1.8/ref/settings/#template-loaders)
50+
- [Django documentation - Templates: Built-in backends](https://docs.djangoproject.com/en/1.8/topics/templates/#module-django.template.backends.django)
51+
52+
Status
53+
------
54+
55+
- `Automated code check available <https://www.quantifiedcode.com/app/pattern/1f408fdeddad425192c87dc2b101fc51>`_
56+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
``TEMPLATE_STRING_IF_INVALID`` deprecated
2+
=========================================
3+
4+
This setting sets the output that the template system should use for invalid (e.g. misspelled) variables. The default value is an empty string ``''``. This setting is deprecated since Django version 1.8. Set the `string_if_invalid` option in the `OPTIONS` of a `DjangoTemplates` backend instead.
5+
6+
Deprecated feature
7+
------------------
8+
9+
Deprecated ``TEMPLATE_STRING_IF_INVALID`` setting used.
10+
11+
.. code:: python
12+
13+
""" settings.py """
14+
15+
TEMPLATE_STRING_IF_INVALID = 'Invalid variable'
16+
17+
Migration path
18+
--------------
19+
20+
As of Django 1.8 you should set ``string_if_invalid`` option in the ``OPTIONS`` of a ``DjangoTemplates`` backend instead.
21+
22+
.. code:: python
23+
24+
""" settings.py """
25+
26+
TEMPLATES = [
27+
{
28+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
29+
'APP_DIRS': True,
30+
'DIRS': '/path/to/my/templates',
31+
'OPTIONS': {
32+
'string_if_invalid': 'Invalid varialbe!',
33+
}
34+
},
35+
]
36+
37+
References
38+
----------
39+
40+
- [Django documentation - Settings: TEMPLATES](https://docs.djangoproject.com/en/1.8/ref/settings/#templates)
41+
- [Django documentation - Settings: TEMPLATE_STRING_IF_INVALID](https://docs.djangoproject.com/en/1.8/ref/settings/#template-string-if-invalid)
42+
- [Django documentation - Templates: Built-in backends](https://docs.djangoproject.com/en/1.8/topics/templates/#module-django.template.backends.django)
43+
- [Django documentation - Templates: How invalid variables are handled](https://docs.djangoproject.com/en/1.8/ref/templates/api/#how-invalid-variables-are-handled)
44+
45+
Status
46+
------
47+
48+
- `Automated code check available <https://www.quantifiedcode.com/app/pattern/6f1b0d6580e04149983617cefa39d08c>`_

docs/django/all/correctness/index.rst

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
:fa:`check` Correctness
2+
=======================
3+
4+
.. toctree::
5+
:maxdepth: 1
6+
7+
not_using_forward_slashes
8+
not_using_null_boolean_field
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
Not using forward slashes
2+
=========================
3+
4+
Django requires you to use forward slashes ``/`` whenever you indicate a path, even on Windows. In your settings, this is true for the following variables.
5+
6+
- ``STATICFILES_DIRS``
7+
- ``TEMPLATE_DIRS``
8+
- ``DATABASES['<your database>'][NAME]``
9+
- ``FIXTURE_DIRS``
10+
11+
Anti-pattern
12+
------------
13+
14+
This pattern is exemplary for any of the above mentioned settings. It uses backslashes, instead of forward slashes.
15+
16+
.. code:: python
17+
18+
""" settings.py """
19+
20+
STATICFILES_DIRS = [
21+
"\path\to\my\static\files",
22+
]
23+
24+
Best practice
25+
-------------
26+
27+
Django requires you to use forward slashes ``/``, even on Windows.
28+
29+
.. code:: python
30+
31+
""" settings.py """
32+
33+
STATICFILES_DIRS = [
34+
"\path\to\my\static\files",
35+
]
36+
37+
References
38+
----------
39+
40+
- [Django documentation - Settings: TEMPLATE_DIRS](https://docs.djangoproject.com/en/1.8/ref/settings/#template-dirs)
41+
- [Django documentation - Settings: FIXTURE_DIRS](https://docs.djangoproject.com/en/1.8/ref/settings/#fixture-dirs)
42+
- [Django documentation - Settings: STATIC_FILES_DIRS](https://docs.djangoproject.com/en/1.8/ref/settings/#https://docs.djangoproject.com/en/1.8/ref/settings/#staticfiles-dirs)
43+
- [Django documentation - Settings: HOST](https://docs.djangoproject.com/en/1.8/ref/settings/#host)
44+
45+
Status
46+
------
47+
48+
- `Automated code check available <https://www.quantifiedcode.com/app/pattern/ff48f625efa5424088acfc1ea788db3e>`_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
Not using ``NullBooleanField``
2+
==============================
3+
4+
A ``BooleanField`` in Django accepts only the two values: ``true`` and ``false``. If you need to accept ``NULL`` values, you have to use a ``NullBooleanField``.
5+
6+
Anti-pattern
7+
------------
8+
9+
The following model uses a ``BooleanField`` with the option ``null=True``, instead of using a ``NullBooleanField``.
10+
11+
.. code:: python
12+
13+
from django.db import models
14+
15+
class Person(models.Model):
16+
first_name = models.CharField(max_length=30)
17+
last_name = models.CharField(max_length=30)
18+
activated = models.BooleanField(null=True)
19+
20+
21+
Best practice
22+
-------------
23+
24+
Use a ``NullBooleanField`` instead:
25+
26+
.. code:: python
27+
28+
from django.db import models
29+
30+
class Person(models.Model):
31+
first_name = models.CharField(max_length=30)
32+
last_name = models.CharField(max_length=30)
33+
# Using NullBooleanField instead
34+
activated = models.NullBooleanField()
35+
36+
Reference
37+
---------
38+
39+
- [Django documentation - Model field reference: BooleanField (https://docs.djangoproject.com/en/1.8/ref/models/fields/#booleanfield)
40+
- [Django documentation - Model field reference: NullBooleanField (https://docs.djangoproject.com/en/1.8/ref/models/fields/#nullbooleanfield)
41+
42+
Status
43+
------
44+
45+
- `Automated code check available <https://www.quantifiedcode.com/app/pattern/f9a71a2aeef846ceafce68f5652b9dad>`_

docs/django/all/index.rst

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Django (all versions)
2+
=====================
3+
4+
This chapter contains anti- and migration patterns that apply to all (recent) Django version.
5+
6+
.. toctree::
7+
:maxdepth: 2
8+
9+
maintainability/index
10+
security/index
11+
correctness/index
12+

0 commit comments

Comments
 (0)