Ensure best practice
Automatically find and fix over 40 issues, so your team can focus on adding value. Reduce costs by preventing tech debt including hidden 404s, migrations blocking production rollback, hard-coded urls, and more.Our maintainability checks
Importing models.py into migrations
Importing models.py into migrations
It's better to use apps.get_model
, which guarantees the Model's fields will reflect the fields in the database even if models.py
is vastly out of step with the database.
Missing reverse migration
Missing reverse migration
It's good to, as a minimum, specify noop
in RunPython
so the migration can be skipped when going backwards, and even better to specify a function that undoes the migration.
Hard-coded static asset URL in template
Hard-coded static asset URL in template
Hard-coding static asset urls is brittle because the place the files are stored depends on the `STATICFILES_STORAGE` used - so if in prod the storage backend uploads to S3 or even renames the file then this hard-coded URL will break.
Using "{% static ... %}" solves that as it knows exactly where the files are stored.
Middleware order
Middleware order
The order of middleware affections the outcome.
Some middleware are dependant on the functionality of other middlware. For example a middleware that requires usage of request.session should come after the SessionMiddleware.
URL name not unique
URL name not unique
URL names must be unique otherwise reverse('url_name')
and {% url 'url_name' %}
will link to the "wrong" page half of the time.
Using reverse_lazy where reverse would be better
Using reverse_lazy where reverse would be better
Using reverse(...)
is better than using reverse_lazy(...)
when the url is being reversed after URLConf
has been loaded.
Middleware should be near the end
Middleware should be near the end
Incorrectly ordered middleware can stop the middleware working as intended.
Middleware should be near the top
Middleware should be near the top
Incorrectly ordered middleware can stop the middleware working as intended.
Hard-coded URL in template
Hard-coded URL in template
Hard-coding urls makes changing URLs harder, and makes linking to the wrong page easier - so harms maintainability.
Brittle unique_for
Brittle unique_for
unique_for_date/month/year
is very brittle and over time will likely be a source for unexpected behaviour.
Importing setting file directly
Importing setting file directly
Using from django.conf import settings
simplifies the code and makes it more maintainable.
CharField with huge max_length
CharField with huge max_length
Using TextField
for very long string fields would simplify the code and make is easier to maintain.
Deprecated NullBooleanField
Deprecated NullBooleanField
NullBooleanField
is deprecated and will be removed a future version of Django.
Redundant default arguments
Redundant default arguments
Stating defaults add complexity when reading the code but does not change Django's behaviour.
Redundant setting
Redundant setting
Stating defaults add complexity when reading the code but does not change Django's behaviour.
Field allows null but not blank
Field allows null but not blank
If null is True
and blank is False
then validation becomes more complex.
Non-unique primary_key
Non-unique primary_key
A non-unique primary key allows the same value to be used for multiple records thus multiple results could be returned for Model.objects.get(pk=1)
.
Relative path in TEMPLATES setting
Relative path in TEMPLATES setting
The TEMPLATE setting is a list of the template engines used when finding template files and rendering them.
The DIRS key within the TEMPLATE list denotes the directories where the engine should look for template source files.
DIRS must be absolute paths. Relative paths will not work.
Back slashes in TEMPLATES settings
Back slashes in TEMPLATES settings
The TEMPLATE setting is a list of the template engines used when finding template files and rendering them.
The DIRS key within the TEMPLATE list denotes the directories where the engine should look for template source files.
DIRS must be forward slashes, even in Windows. Forward slashes do not need escaping, and they are cross Operating System compatible.
Nullable string field
Nullable string field
ORM queries and Python code are made more complex because values will sometimes be None
and other times str
.
ForeignKey missing related_name
ForeignKey missing related_name
ORM queries are more readable and relationships more explicit when related_name
is specified.
Model method order
Model method order
Increasing standardisation and predictability of your code style helps other developers read your code.
Admin class not in admin.py
Admin class not in admin.py
Predictable project structure and following common patterns simplifies maintenance of a codebase.
Django developers come to expect Admin-related objects to be in admin.py. Failure to do this will result in more time spent looking for where code lives.
Tall Model
Tall Model
A taller Model with many fields may be more difficult to maintain than a shorter Model with fewer fields.
Huge models.py
Huge models.py
Taller models.py
with many Models may be more difficult to maintain than shorter models.py
with fewer Models.
Tall models.py with a common prefix
Tall models.py with a common prefix
Taller models.py
with many Models may be more difficult to maintain than shorter models.py
with fewer Models.