Custom django management command with appended parameters

自闭症网瘾萝莉.ら 提交于 2019-12-24 11:34:44

问题


My team runs a custom test suite pretty regularly. When we want to run the whole thing, we do

./manage.py test --keepdb --failfast --settings=AE.test_settings

When we want to run tests on a specific app, we do the same, but with the app name include.

I'd like to make a custom management command that, when called, will run the default test suite, but append the --keepdb, --failfast, and --settings=AE.test_settings params. Ideally something like

./manage.py aetest

That can also be run with app names, such that

./manage.py aetest registration

Would be the same as running

./manage.py test registration --keepdb --failfast --settings=AE.test_settings

My attempt so far is

from django.core.management.base import BaseCommand, CommandError
from django.core import management

class Command(BaseCommand):

    def handle(self, *args, **kwargs):
        positional_arguments = [
            '--keepdb',
            '--failfast',
            '--settings=NJ.test_settings',
        ]
        for item in args:
            positional_arguments.append(item)
        keyword_arguments = {
            'settings': "AE.test_setings",  
        }
        keyword_arguments.update(kwargs)
        management.call_command("test", *positional_arguments, **keyword_arguments)

If I try to pass further positional arguments, my command errors out in such a way as to imply they were never passed. And the keyword argument never makes it to the call_command (the command runs with my default settings.py file)

Any idea how I can have this management command accept additional positional and keyword parameters, but append the desired ones automatically?

Thanks!

UPDATE

I was given the great idea of subclassing BaseTestCommand. While this seems to work for True/False variables, passing the settings variable doesn't seem to work. If I use the following code:

class Command(BaseTestCommand):
    def handle(self, *test_labels, **options):
        options['failfast'] = True
        options['keepdb'] = True
        options['settings'] = "AE.test_settings"
        print(options)

        super(Command, self).handle(*test_labels, **options)

Running my new command uses the failfast and the keepdb, but it still uses the default settings.py for my project. Any idea why this might be?

Side note: running the new command with --settings=AE.test_settings works like a charm


回答1:


You could subclass the Django test command and override the handle method to set the options you need.

from django.core.management.commands.test import Command as BaseTestCommand


class Command(BaseTestCommand):
    def handle(self, *test_labels, **options):
        options['failfast'] = True
        options['keepdb'] = True
        options['settings'] = 'NJ.test_settings'

        super(Command, self).handle(*test_labels, **options)

As to why your code does not work, it is because your are misusing the call_command function. Every command option (that starts with --) must be passed as a keyworded argument even if it is boolean, your handle method should then be:

def handle(self, *args, **kwargs):
    kwargs.update({
        'settings': 'NJ.test_settings',
        'keepdb': True,
        'failfast': True
    })
    management.call_command("test", *args, **kwargs)


来源:https://stackoverflow.com/questions/32889914/custom-django-management-command-with-appended-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!