Ошибка пользовательской команды Django: непризнанные аргументы

Я пытаюсь создать команду, похожую на createsuperuser, которая будет принимать два аргумента (имя пользователя и пароль)

Работает отлично в django 1.7, но не в 1.8. (Я также использую python3.4)

это код, который я написал

MyApp/Управление/Команды/createmysuperuser.py

from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import User


class Command(BaseCommand):
    help = 'Create a super user'

    def handle(self, *args, **options):

        if len(args) != 2:
            raise CommandError('need exactly two arguments for username and password')
        username, password = args

        u, created = User.objects.get_or_create(username=username)
        if created:
            u.is_superuser = True
            u.is_staff = True
            u.set_password(password)
            u.save()
        else:
            raise CommandError("user '%s' already exist" % username)

        return "Password changed successfully for user '%s'" % u.username

и когда я пытаюсь запустить эту команду

$ python manage.py createmysuperuser myuser mypassword

Я получаю эту ошибку

usage: manage.py createmysuperuser [-h] [--version] [-v {0,1,2,3}]
                                   [--settings SETTINGS]
                                   [--pythonpath PYTHONPATH] [--traceback]
                                   [--no-color]
manage.py createmysuperuser: error: unrecognized arguments: myuser mypassword

но когда я не передаю какие-либо аргументы, он поднимает CommandError, который ожидается.

CommandError: need exactly two arguments for username and password

Ответы

Ответ 1

В django 1.8 вы должны добавить аргументы к команде:

class Command(BaseCommand):
    ...
    def add_arguments(self, parser):
        parser.add_argument('username')
        parser.add_argument('password')

add_argument() метод argparse описан здесь.

UPDATE. По умолчанию аргументы передаются в параметре options, поэтому метод handle() должен выглядеть следующим образом:

def handle(self, *args, **options):
    username = options['username']
    password = options['password']
    ...

И вам не нужно проверять длину списка args - это уже сделано с помощью argparse. Это рекомендуемый метод, но если вы хотите использовать аргумент args, тогда вы должны использовать "режим совместимости" и называть добавленный аргумент как args:

class Command(BaseCommand):

    def add_arguments(self, parser):
        parser.add_argument('args')

    def handle(self, *args, **options):
        if len(args) != 2:
            ...

Прочитайте примечание "Изменено в Django 1.8" в первой главе документов (сразу после примера closepoll.py).

UPDATE2. Вот полный рабочий пример:

from django.core.management.base import BaseCommand    

class Command(BaseCommand):

    def add_arguments(self, parser):
        parser.add_argument('username')
        parser.add_argument('password')

    def handle(self, *args, **options):
        username = options['username']
        password = options['password']
        return u'Username: %s  Password: %s' % (username, password)