I've been trying to redirect the standard output of a custom django command using this piece of code:
from django.core.management.base import BaseCommand
from django.core import management
class Command(BaseCommand):
def handle(self, *args, **options):
f = open('/tmp/output', 'r+')
management.call_command('basequery', 'list', 'log', stdout=f)
f.close()
However, when I call this from manage.py the standard output appears on the console and the /tmp/output file is created but empty.
Here's the django documentation of what I'm trying to do
Your command is probably just using print
directly. To be able to capture or redirect prints in a management command, you'll want to use the self.stdout
handle of the command instance:
from __future__ import print_function
class Command(BaseCommand):
def handle(self, *args, **options):
# incorrect way to print in a management command:
print('This line will go to the terminal')
# correct ways to print in a management command:
print('This line will go into the StringIO', file=self.stdout)
self.stdout.write('This will also go into the StringIO')
If you're unable change the print calls within the command (which is the code within 'basequery'
in your example), then you can use a context manager to temporarily redirect stdout in order to capture that output. It's important to restore the old stdout after redirection. See contextlib.redirect_stdout
.
If you have control over the code of the management command, then you should follow the answer by @wim. This answer assumes you can't/won't change the command itself.
The method by @Igor is the best way when available, but some commands ignore stdout
argument.
@Phob1a has a solution that is basically okay but has the problem of closing stdout
(so future output to it doesn't work). With some changes:
from django.core.management import call_command
import sys
stdout_backup, sys.stdout = sys.stdout, open('output_file', 'w+')
call_command('your_command')
sys.stdout = stdout_backup
Note that if you want to just throw away output, you should replace the first command:
from os import devnull
stdout_backup, sys.stdout = sys.stdout, open(devnull, 'a')
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With