Over a million developers have joined DZone.
Platinum Partner

Subclassing Django's runserver causes command to be run twice

· DevOps Zone

The DevOps Zone is brought to you in partnership with New Relic.  Download 5 Unsung Tools of DevOps to see which tools make the cut and why.

This week I was creating my own version of the Django management command runserver. Like the built-in, I wanted to run a lightweight development only web server for my Django app. In addition, I was looking to run a syncdb, load some initial data and start up the server with that. The goal was to use an in-memory sqlite3 database, and use this command as a way to spin up an interactive test instance.

This is easily achieved by using call_command to call syncdb and runserver in sequence. The in-memory sqlite3 config I would leave to a Django settings file. But I noticed that syncdb seemed to be getting called twice, leading to double the start up time.

Rooting around in the Django bug database, I found that this was a known issue with the default auto-reloading functionality of runserver. The solution turned out to be a simple as disabling that functionality by passing an option to the native runserver when you use call_command.

import os
from django.core.management import call_command
from django.core.management.base import BaseCommand
from django.core.management.commands.runserver import BaseRunserverCommand


class Command(BaseCommand):
    ''' Runs the built-in Django runserver with initial schema and fixtures
    Note: cannot use auto-reloading because that casues resetdb to be called
    twice.
    '''

    # remove this option from the --help for this command
    option_list = (o for o in BaseRunserverCommand.option_list if o.dest != 'use_reloader')
    help = 'Starts a lightweight web server testing.'
    args = '[optional port number, or ipaddr:port] appname appname'

    def handle(self, addrport='', *args, **options):
        call_command('syncdb', *args, **options)
        # BUG: runserver gets called twice if --noreload is False
        # https://code.djangoproject.com/ticket/8085
        options['use_reloader'] = False
        call_command('runserver', addrport, *args, **options)

The DevOps Zone is brought to you in partnership with New Relic.  Read about where DevOps started and how the adoption rate went from tiny startups to giant Fortune 500 enterprises.

Topics:

Published at DZone with permission of Chase Seibert , DZone MVB .

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}