{ "info": { "author": "Erik Rose", "author_email": "erikrose@grinchcentral.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Topic :: Software Development :: Libraries" ], "description": "===================\ndjango-subcommander\n===================\n\nUse django-subcommander to write Django management commands that have\nsubcommands, each optionally having its own distinct options, help, and other\ntypically per-command behavior. Subcommands are just normal Django\n``BaseCommand`` subclasses, so there's very little new to learn. Here's an\nexample top-level command; you'd put this in your app's\n``management.commands.desserts`` module::\n\n from django_subcommander import SubcommandDispatcher\n\n\n class Command(SubcommandDispatcher):\n \"\"\"The top-level \"dessert\" command which has several subcommands\"\"\"\n\n help = 'Eat, top, and do various things with desserts.'\n args = ' [more arguments and options]'\n\n def _subcommand(self, name):\n \"\"\"\n Return a management command that implements the subcommand of the\n given name.\n \"\"\"\n if name == 'eat':\n return EatCommand()\n elif name == 'top':\n ,,,\n\n\n class EatCommand(BaseCommand):\n # You could put this in another module or wherever you want.\n help = 'Eat a dessert.'\n args = '[number of bites]'\n\n # Add options here with make_option(), in the usual way.\n\n def handle(self, *args, **options):\n ...\n\nTo invoke the subcommand for eating a dessert in 5 bites... ::\n\n ./manage.py dessert eat 5\n\nTo see the help for the ``eat`` subcommand... ::\n\n ./manage.py dessert eat --help\n\nTo see the help for the top-level command... ::\n\n ./manage.py dessert --help\n\nThe help for the top-level command will list its subcommands if you implement\n``_subcommand_names``::\n\n class Command(SubcommandDispatcher):\n ...\n\n def _subcommand(self, name):\n ...\n\n def _subcommand_names(self):\n \"\"\"Return a list of the names of all the subcommands.\"\"\"\n return ['eat', 'top']\n\nThen, ``./manage.py dessert --help`` will result in something like this::\n\n Usage: ...\n\n Options:\n ...\n\n Subcommands:\n eat [number of bites]\n top [more toppings]\n\n\nCrazy Stuff\n===========\n\n* Notice that ``_subcommand()`` returns a command instance, not a class or a\n module path. Not only does this give you the freedom to put your subcommand\n code wherever you wish, but it also means you can generate or parametrize\n subcommands dynamically, at runtime.\n* There's no reason you shouldn't be able to have one ``SubcommandDispatcher``\n return another, thereby implementing multi-level subcommands.\n\n\nDesign Notes\n============\n\nDjango's management command framework is built on ``optparse``, not the more\nmodern ``argparse``, which supports subcommands natively. It would be quite a\nbit of gluing to get ``argparse`` working with Django's management command\ninfrastructure, so I took the simple road. This lets authors reuse everything\nthey already know about writing Django management commands. For example, I had\nseveral groups of pre-existing commands I wanted to organize under a handful of\nsubcommands. This let me avoid having hundreds of individual files under\n``management/commands``; it gave me the freedom to locate all that command code\nelsewhere and organize it in a more natural way. Turning the commands into\nsubcommands required no changes to them at all.\n\ndjango-subcommander is definitely a \"worse is better\" solution. It's an eminently practical solution to the profusion of files in ``management/commands``. If it had turned out long and complicated, I probably would have rigged Django to support argparse-based commands instead...hmm, what about making a BaseCommand alternative that's argparse-based?\n\n\nFuture Plans\n============\n\n* Tests. I'm using it all day now, but I've been testing it only \"in situ\".\n* More flexibility in how to display the list of subcommands when getting\n ``--help`` on the top-level command\n* Support for Django's other command superclasses like ``AppCommand`` and\n ``LabelCommand`` (if, in fact, they don't work already and if there's demand)\n* I went a short way down the path of giving ``_subcommand()`` access to the\n whole ``argv`` and having it return any args that weren't used to do\n dispatch. This ended up complicating things significantly for unclear\n benefit. If you'd find this useful, please file a bug.\n\n\nVersion History\n===============\n\n0.1\n First release.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/votizen/django-subcommander", "keywords": "django,subcommand,command,nested,management", "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "django-subcommander", "package_url": "https://pypi.org/project/django-subcommander/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-subcommander/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/votizen/django-subcommander" }, "release_url": "https://pypi.org/project/django-subcommander/0.1/", "requires_dist": null, "requires_python": null, "summary": "Write Django management commands that have subcommands.", "version": "0.1" }, "last_serial": 790790, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "d980872821db68f1b66b0db798b606e3", "sha256": "1a856abb2e8f7feb8ebace0051f8c8eeee27273caba8612e115ac4a210f24b4d" }, "downloads": -1, "filename": "django-subcommander-0.1.tar.gz", "has_sig": false, "md5_digest": "d980872821db68f1b66b0db798b606e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5874, "upload_time": "2012-08-15T18:20:18", "url": "https://files.pythonhosted.org/packages/8d/ef/842c7e626d9a6967bcd59027f5d0aa35b4a05c1949473de0456c378c52fc/django-subcommander-0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d980872821db68f1b66b0db798b606e3", "sha256": "1a856abb2e8f7feb8ebace0051f8c8eeee27273caba8612e115ac4a210f24b4d" }, "downloads": -1, "filename": "django-subcommander-0.1.tar.gz", "has_sig": false, "md5_digest": "d980872821db68f1b66b0db798b606e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5874, "upload_time": "2012-08-15T18:20:18", "url": "https://files.pythonhosted.org/packages/8d/ef/842c7e626d9a6967bcd59027f5d0aa35b4a05c1949473de0456c378c52fc/django-subcommander-0.1.tar.gz" } ] }