Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is run called twice in the Django dev server?

Tags:

I want to make the Django development server do something before it starts running. To do this, I created a new app, added it to the top of INSTALLED_APPS, and then created a management/commands/runserver.py file in the app with the following code:

from django.contrib.staticfiles.management.commands.runserver import Command as RunserverCommand
class Command(RunserverCommand):
    def run(self, *args, **options):
        self.stdout.write('About to start running on ' + self.addr)
        super(Command, self).run(*args, **options)

(The thing I actually want to do is more complicated than writing one line to stdout, of course, but this is the simplest example that demonstrates the problem. The reason I override run, rather than handle or some other method, is because I need self.addr to already be set when this code runs.)

When I run ./manage.py runserver, the line "About to start running on 127.0.0.1" appears not once, but twice before the server starts running. Why is this happening and what can be done about it?

like image 347
Taymon Avatar asked Feb 12 '15 23:02

Taymon


People also ask

How do I keep Django server running?

Start your server there. Then press Ctrl-a, then d. This detach the screen session, keeping it running in the background.

What is the command to start Django's built in development server?

python manage.py runserver The runserver command is a built-in subcommand of Django's manage.py file that will start up a development server for this specific Django project.


1 Answers

The auto-reloader process turned out to be the culprit; turns out the autoreload process gets the same arguments, and goes through the same initialization process, as the original. The solution was to have the pre-server code execute only if it's not running in the process spawned by the autoreloader, which can be detected through an environment variable:

import os
from django.contrib.staticfiles.management.commands.runserver import Command as RunserverCommand
class Command(RunserverCommand):
    def run(self, *args, **options):
        if os.environ.get('RUN_MAIN') != 'true':
            self.stdout.write('About to start running on ' + self.addr)
        super(Command, self).run(*args, **options)
like image 73
Taymon Avatar answered Sep 22 '22 17:09

Taymon