• Take note: this article is incomplete and about an older LTS version of Django.


This article is part of a series:

Django basics
  1. Django basics: General tips and tricks
  2. Django basics: Apps

Important: This article is unfinished, and I am publishing it early to share it with colleagues. Copy may be changed or added where necessary. Please send any feedback or ideas to me via Twitter or LinkedIn!

This article is part of a series. In this series, I provide beginner tips for the Django framework. The code examples use Django 2.2, the latest stable LTS (long-term support) version of Django at the time of writing.

In this edition, I'm sharing with you some random, general tips and tricks.

Zen of Python

https://www.python.org/dev/peps/pep-0020/

Do not be afraid to make mistakes

This is general programming advice: when you are developing an application you should not be afraid to make mistakes. Assuming you haven't hooked your local environment to a production database you can freely write, test, and break your code.

Enable debug mode and enjoy the wealth of information an error page provides you with when—not if—things break down. Remember: seasoned programmers get scared when code works on its first run.

RTFM

This is your general reminder that Django and each third-party packages come (or should come) with a manual. Read it, use it, refer to it. Even if you have used a particular feature for a long time you can still gain new insights.

When upgrading packages, make sure to read upon changes between major versions of the framework and libraries. Django also provides deprecation warnings in older versions to notify you about (upcoming) breaking changes.

Show deprecation warnings

When you are developing your Django application, you are likely using the management command runserver to run Django. At this point you can enable Python deprecation warnings to help you show you warnings about features that will be removed in the near feature.

This option is particularly useful when preparing for a Django upgrade:

./manage.py python -Wd /code/manage.py runserver

Django is Python, Python is not Django

Django is a web framework built on Python, and you can use whatever Python module is available in your project. In some cases—unit tests for example—there is an additional Django layer built on top of a Python package. Read the feature's documentation to find out which code you need to use.

Don't forget init files

Add a file__init__.py to all your Python module directories. This file tells Python that it is dealing with a package containing submodules. If Django cannot find app modules that do exist, a missing __init__.py may be the culprit.

Note: An init file can be used as a regular Python module, but is often empty in the context of Django applications.

Make every bit of copy translatable

Your application likely contains a lot of text that is shown to the user—often referred to as "copy". Copy is not ready for translation by default, but you can make it so. Read Django 2.2 translation documentation on how to make this happen.

Note: You do not actually have to translate your app, just make it ready for when someone does want to do it. Adding translation functions afterwards is a bad chore, trust me.

Use lazy translation functions

There are two variants of each translation function: an active and lazy one. Unlike the active version, the lazy version gets executed only when it is used.

Lazy translation is useful when adding translations in places where direct execution of the translate function would cause a runtime error, usually when the translation framework hasn't been initiated by the time your code gets run.

This is the import you want to use:

from django.utils.translation import gettext_lazy as _

Keep in mind that the return type of a lazy-translated string is not actually str, but an object that resolves to a string. This is usually fine, but causes errors in methods that require a string type return value; one such method is __str__(). You can choose to use active translation in such cases, or cast lazy-translated items to string type using str().

Documentation. Documentation. Documentation.

Your code should document itself as much as possible, but you also want to write down the things that the code cannot tell you. I've already written an article about this:  Why you should and should not write code documentation .