2015-08-16 15 views
6

मैं Django के call_command का उपयोग this question without an answer के समान तरीके से करने की कोशिश कर रहा हूं।call_command तर्क की आवश्यकता है

तरह से मैं यह फोन कर रहा हूँ है:

args = [] 
    kwargs = { 
     'solr_url': 'http://127.0.0.1:8983/solr/collection1', 
     'type': 'opinions', 
     'update': True, 
     'everything': True, 
     'do_commit': True, 
     'traceback': True, 
    } 
    call_command('cl_update_index', **kwargs) 

सिद्धांत रूप में, कि, काम करना चाहिए the docs के अनुसार। लेकिन यह काम नहीं करता है, यह सिर्फ नहीं करता है।

यहाँ मेरी कमान वर्ग के लिए add_arguments विधि है:

def add_arguments(self, parser): 
    parser.add_argument(
     '--type', 
     type=valid_obj_type, 
     required=True, 
     help='Because the Solr indexes are loosely bound to the database, ' 
      'commands require that the correct model is provided in this ' 
      'argument. Current choices are "audio" or "opinions".' 
    ) 
    parser.add_argument(
     '--solr-url', 
     required=True, 
     type=str, 
     help='When swapping cores, it can be valuable to use a temporary ' 
      'Solr URL, overriding the default value that\'s in the ' 
      'settings, e.g., http://127.0.0.1:8983/solr/swap_core' 
    ) 

    actions_group = parser.add_mutually_exclusive_group() 
    actions_group.add_argument(
     '--update', 
     action='store_true', 
     default=False, 
     help='Run the command in update mode. Use this to add or update ' 
      'items.' 
    ) 
    actions_group.add_argument(
     '--delete', 
     action='store_true', 
     default=False, 
     help='Run the command in delete mode. Use this to remove items ' 
      'from the index. Note that this will not delete items from ' 
      'the index that do not continue to exist in the database.' 
    ) 
    parser.add_argument(
     '--optimize', 
     action='store_true', 
     default=False, 
     help='Run the optimize command against the current index after ' 
      'any updates or deletions are completed.' 
    ) 
    parser.add_argument(
     '--do-commit', 
     action='store_true', 
     default=False, 
     help='Performs a simple commit and nothing more.' 
    ) 

    act_upon_group = parser.add_mutually_exclusive_group() 
    act_upon_group.add_argument(
     '--everything', 
     action='store_true', 
     default=False, 
     help='Take action on everything in the database', 
    ) 
    act_upon_group.add_argument(
     '--query', 
     help='Take action on items fulfilling a query. Queries should be ' 
      'formatted as Python dicts such as: "{\'court_id\':\'haw\'}"' 
    ) 
    act_upon_group.add_argument(
     '--items', 
     type=int, 
     nargs='*', 
     help='Take action on a list of items using a single ' 
      'Celery task' 
    ) 
    act_upon_group.add_argument(
     '--datetime', 
     type=valid_date_time, 
     help='Take action on items newer than a date (YYYY-MM-DD) or a ' 
      'date and time (YYYY-MM-DD HH:MM:SS)' 
    ) 

कोई फर्क नहीं पड़ता कि मैं क्या यहां करते हैं, मैं:

CommandError: Error: argument --type is required

कोई भी विचार? यदि आप वास्तव में उत्सुक हैं, तो आप see the entire code here कर सकते हैं।

+0

कार्रवाई = store_true और डिफ़ॉल्ट = झूठी एक-दूसरे से विरोधाभास करते हैं। 'store_true'' store_const' के लिए एक उपनाम है 'const = True' – Incognos

उत्तर

10

आपने '--type' ध्वज के साथ एक तर्क परिभाषित किया है, और इसे required बनाया है। उस कमांड लाइन को स्ट्रिंग या स्ट्रिंग की आवश्यकता होगी जो --type avalue जैसा दिखता है।

यह call_command के संबंधित भाग की तरह दिखता है:

def call_command(name, *args, **options): 
    .... 
    parser = command.create_parser('', name) 
    if command.use_argparse: 
     # Use the `dest` option name from the parser option 
     opt_mapping = {sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest 
         for s_opt in parser._actions if s_opt.option_strings} 
     arg_options = {opt_mapping.get(key, key): value for key, value in options.items()} 
     defaults = parser.parse_args(args=args) 
     defaults = dict(defaults._get_kwargs(), **arg_options) 
     # Move positional args out of options to mimic legacy optparse 
     args = defaults.pop('args',()) 

यह एक पार्सर बनाता है, जिसे खुद तर्क प्लस वन आप जोड़ना है का उपयोग कर।

parser._actions if s_opt.option_strings तर्क (क्रियाएं) हैं जो एक विकल्प ध्वज (साथ शुरू करें - या -) लेते हैं। opt_mapping ध्वज तारों (शून्य से अग्रणी) और 'dest' विशेषता के बीच नक्शा है।

arg_options को parser आउटपुट के साथ विलय किया जा सकता है।

defaults = parser.parse_args(args=args) वास्तविक पार्सिंग करता है। यही है, यह एकमात्र कोड है जो वास्तव में argparse पार्सिंग तंत्र का उपयोग करता है। इसलिए *args आपके कॉल का हिस्सा एक इंटरैक्टिव कॉल से sys.argv[1:] उत्पन्न करता है।

कि पढ़ने के आधार पर मुझे लगता है कि यह काम करना चाहिए:

args = [ 
    '--solr-url', 'http://127.0.0.1:8983/solr/collection1', 
    '--type', 'opinions', 
    '--update' 
    '--everything', 
    '--do_commit', 
    '--traceback', 
} 
call_command('cl_update_index', *args) 

के बजाय **kwargs मैं स्ट्रिंग की एक सूची के रूप में मूल्यों में गुजर रहा हूँ। या दो आवश्यक तर्क args में और **kwargs में दिए जा सकते हैं।

args = ['--solr-url', 'http://127.0.0.1:8983/solr/collection1', 
    '--type', 'opinions'] 
kwargs = { 
    'update': True, 
    'everything': True, 
    'do_commit': True, 
    'traceback': True, 
} 
call_command('cl_update_index', *args, **kwargs) 

एक तर्क है required यह *args के माध्यम से में पारित करने की जरूरत है। **kwargs पार्सर को बाईपास करता है, जिससे यह अनुपस्थित तर्कों के बारे में ऑब्जेक्ट करता है।


मैं नवीनतम django डाउनलोड किया है, लेकिन यह स्थापित नहीं किया है।

import argparse 

def call_command(name, *args, **options): 
    """ 
    Calls the given command, with the given options and args/kwargs. 
    standalone simulation of django.core.mangement call_command 
    """ 
    command = name 
    """ 
    .... 
    """ 
    # Simulate argument parsing to get the option defaults (see #10080 for details). 
    parser = command.create_parser('', name) 
    if command.use_argparse: 
     # Use the `dest` option name from the parser option 
     opt_mapping = {sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest 
         for s_opt in parser._actions if s_opt.option_strings} 
     arg_options = {opt_mapping.get(key, key): value for key, value in options.items()} 
     defaults = parser.parse_args(args=args) 
     defaults = dict(defaults._get_kwargs(), **arg_options) 
     # Move positional args out of options to mimic legacy optparse 
     args = defaults.pop('args',()) 
    else: 
     # Legacy optparse method 
     defaults, _ = parser.parse_args(args=[]) 
     defaults = dict(defaults.__dict__, **options) 
    if 'skip_checks' not in options: 
     defaults['skip_checks'] = True 

    return command.execute(*args, **defaults) 

class BaseCommand(): 
    def __init__(self): 
     self.use_argparse = True 
     self.stdout= sys.stdout 
     self.stderr=sys.stderr 
    def execute(self, *args, **kwargs): 
     self.handle(*args, **kwargs) 
    def handle(self, *args, **kwargs): 
     print('args: ', args) 
     print('kwargs: ', kwargs) 
    def create_parser(self, *args, **kwargs): 
     parser = argparse.ArgumentParser() 
     self.add_arguments(parser) 
     return parser 
    def add_arguments(self, parser): 
     parser.add_argument('--type', required=True) 
     parser.add_argument('--update', action='store_true') 
     parser.add_argument('--optional', default='default') 
     parser.add_argument('foo') 
     parser.add_argument('args', nargs='*') 

if __name__=='__main__': 

    testcmd = BaseCommand() 
    # testcmd.execute('one','tow', three='four') 

    call_command(testcmd, '--type','typevalue','foovalue', 'argsvalue', update=True) 

    args = ['--type=argvalue', 'foovalue', '1', '2'] 
    kwargs = { 
     'solr_url': 'http://127.0.0.1...', 
     'type': 'opinions', 
     'update': True, 
     'everything': True, 
    } 
    call_command(testcmd, *args, **kwargs) 

जो पैदा करता है: लेकिन यहाँ call_command के अनुकरण कि फोन करने के लिए विकल्पों का परीक्षण करना चाहिए है

python3 stack32036562.py 
args: ('argsvalue',) 
kwargs: {'optional': 'default', 'type': 'typevalue', 'update': True, 'skip_checks': True, 'foo': 'foovalue'} 
args: ('1', '2') 
kwargs: {'optional': 'default', 'update': True, 'foo': 'foovalue', 'type': 'opinions', 'skip_checks': True, 'everything': True, 'solr_url': 'http://127.0.0.1...'} 

स्टब्स का एक समूह के साथ, मैं अपने BaseCommand के साथ अपने clCommand काम कर सकते हैं, और निम्न कॉल काम करता है:

clupdate = Command() 
args = ['--type','opinions','--solr-url','dummy'] 
kwargs = { 
    'solr_url': 'http://127.0.0.1:8983/solr/collection1', 
    #'type': 'opinions', 
    'update': True, 
    'everything': True, 
    'do_commit': True, 
    'traceback': True, 
} 
call_command(clupdate, *args, **kwargs) 

एक स्टब everything प्रदर्शन कर रहा है।

Running in update mode... 
everything 
args: () 
options: {'type': 'opinions', 'query': None, 'solr_url': 'http://127.0.0.1:8983/solr/collection1', 'items': None, 'do_commit': True, 'update': True, 'delete': False, 'datetime': None, 'optimize': False, 'skip_checks': True, 'everything': True, 'traceback': True} 
+0

हाँ, दस्तावेज़ बहुत अच्छे नहीं हैं, लेकिन मैंने दोनों तरीकों से प्रयास किया है। – mlissner

+1

'django' कोड पढ़ने के आधार पर, मुझे लगता है कि 'आवश्यक' तर्क' * args' के माध्यम से दिए जाने की आवश्यकता है, न कि '** kwargs'। – hpaulj

+0

महान जवाब, हालांकि मैं अभी भी एक ताना के रूप में कुछ भी पारित करने में सक्षम नहीं था। यहां तक ​​कि सामान जो आपने कहा * * काम करना चाहिए? काम नहीं किया मेरे लिए यह काम करने का एकमात्र तरीका सूची के रूप में सबकुछ पास करना है। – mlissner

संबंधित मुद्दे