0

In my Django site, I'm writing a management command to generate sample data in fixtures for all models, or the specified model.

The first (and only) positional arg should specify the app.model to process, or "all" to do all models.

The problem I'm having is that the arg is a tuple, and when I print it, it shows individual characters as each element of the tuple.

Here's my code (as far as showing the arg):

    def add_arguments(self, parser):
        parser.add_argument(
            'args', type=str, metavar='app.model', nargs='?', default='all',
            help='Model in the form: app.model (example: clients.client)')

    def handle(self, *args, **kwargs):
        self.model = args

        print('args-type:', type(args))
        print('model-type:', type(self.model))
        print('model:', self.model)

Note that I've specified type=str as an add_argument option.

When I try this command line:

docker-compose exec api python manage.py gen_fixtures

...I get this output:

args-type: <class 'tuple'>
model-type: <class 'tuple'>
model: ('a', 'l', 'l')

It's the same if I specify "all" on the command line. And if I try this one:

docker-compose exec api python manage.py gen_fixtures clients.client

...I get this output:

args-type: <class 'tuple'>
model-type: <class 'tuple'>
model: ('c', 'l', 'i', 'e', 'n', 't', 's', '.', 'c', 'l', 'i', 'e', 'n', 't')

I know that if I'm initializing a tuple in my code with a single value, like my_var = ('one value',) and forget to add the trailing comma, I'll get the same results as above. But in this case, the tuple is being created in the parser, beyond my control. And why is the type=str not having any effect?

I just want a single arg as a string. How can I do that?

2
  • Please also post how do you call handle. Commented Aug 13, 2019 at 7:00
  • That is done by the parent class. My class is defined as class Command(BaseCommand). But I found where handle is being called in BaseCommand... output = self.handle(*args, **options) Commented Aug 13, 2019 at 7:10

1 Answer 1

2

You're confusing two things here. *args is a built-in Python way of passing variable arguments to a function; it will always be a tuple. It has nothing to do with the command-line option which you happen to have also called args. You need to get that from the dictionary provided in the second parameter.

def handle(self, *args, **kwargs):
    self.model = kwargs['args']
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.