Have you ever tried to add a helpful output for showing the progress of a slow management command but all the output frustratingly appears in one go after the script has finished? You’ve tripped into something called output buffering and luckily it’s very easy to fix.
Use self.stdout
instead of print
in management commands
You should never use print
inside Django management commands as they have a special self.stdout
method that makes testing easier. This method frustratingly takes slightly different arguments than print, but it also has more features like styling. Here’s how you would do a simple row of dots that grows iteratively:
self.stdout(".", ending="", flush=True) self.stdout.flush()
Note the flush()
. This is wat forces the output to be shown to the user before the script finishes. And the same with print:
print(".", end="", flush=True)
Both self.stdout
and print
will add newline to the output by default but you can disable that by explicitly setting the ending as an empty string. And when you flush your output manually, you’ll get nice and interactive console output for your management commands — voilà!
(Btw. If you have ever wondered about ENV PYTHONUNBUFFERED 1
in some of the Docker images for Python, this is why; disabling output buffering makes reading Docker logs way easier.)