17👍
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
.
8👍
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')
...
- When is it appropriate to use Django context processors?
- Django Storages – Could Not Load Amazon's S3 Bindings Errors
- Django-allauth SITE_ID error
- How to pass data between django views
0👍
I am using this to redirect output to file
f = open('/path/to/file', 'w')
buf = StringIO()
call_command('compile_game_data', 'kingdom', indent=4, stdout=buf)
buf.seek(0)
f.write(buf.read())
f.close()
-2👍
I tried Igor’s approximation using the following code:
class Command(BaseCommand):
def handle(self, *args, **options):
f = open('/tmp/output', 'w+')
out = StringIO()
management.call_command('basequery', 'list', 'log', stdout=out)
out.seek(0)
f.write(out.read())
f.close()
I got the same result tough: empty file and stdout appearing in the console. Maybe that’s because I’m calling django commands from a django command?
Anyway, I managed to solve the problem this way:
sys.stdout = open('/tmp/output', 'w+')
management.call_command('basequery', 'list', 'log')
sys.stdout.close()
I know it is an ugly solution but it’s the only way I made it work.
- You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware
- How do I write a Django model with ManyToMany relationsship with self through a Model
- Django template object type