Comandos de administración: comandos ejecutados desde la línea de comandos utilizando el script manage.py.
Las áreas más comunes de aplicación son acciones que se realizan una vez o periódicamente, pero para las cuales el lanzamiento a través del programador no está disponible por alguna razón. Por ejemplo, enviar mensajes únicos a los usuarios, recuperar datos de una base de datos, verificar la presencia de los archivos y carpetas necesarios antes de realizar actualizaciones, crear rápidamente objetos modelo durante el desarrollo, etc.
Los fundamentos
Los comandos se crean en directorios de aplicaciones (las aplicaciones deben agregarse a INSTALED_APPS), en el subdirectorio de aplicaciones / administración / comandos. Se crea un archivo separado para cada comando. Los archivos estarán disponibles desde la línea de comandos, excepto aquellos que comienzan con un guión bajo.
app/ __init__.py management/ __init__.py commands/ __init__.py _tools.py zen.py
En este ejemplo, el comando zen estará disponible, pero _tools no lo estará.
Los comandos se crean heredando de la clase django.core.management.base.BaseCommand. En el caso más simple, es suficiente reescribir la función del controlador. Este comando se ejecutará y el resultado que devuelva se imprimirá en la consola.
from django.core.management.base import BaseCommand class Command(BaseCommand): help = 'The Zen of Python' def handle(self, *args, **options): import this
Intentemos llamar a nuestro comando:
python manage.py zen The Zen of Python, by Tim Peters Beautiful is better than ugly. ...
El atributo de la clase de ayuda es una descripción que se muestra cuando se llama a un comando con el modificador --help o si el comando se ingresa incorrectamente.
$ python manage.py zen --help usage: manage.py zen [-h] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] The Zen of Python optional arguments: -h, --help show this help message and exit --version show program's version number and exit -v {0,1,2,3}, --verbosity {0,1,2,3} Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output --settings SETTINGS The Python path to a settings module, eg "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used. --pythonpath PYTHONPATH A directory to add to the Python path, eg "/home/djangoprojects/myproject". --traceback Raise on CommandError exceptions --no-color Don't colorize the command output.
Analizando argumentos
Como podemos ver, nuestro equipo ya está tomando 7 argumentos.
Pero, ¿qué pasa si esto no es suficiente para nosotros y queremos agregar nuestras propias opciones? Para hacer esto, debe crear la función add_arguments en nuestra clase, donde enumerar todos los argumentos que queremos pasar a nuestro equipo. Cada argumento se crea llamando a la función parser.add_argument con una serie de parámetros.
Supongamos que no nos sentimos cómodos con la salida larga de nuestra función, y queremos que solo Hello world se imprima con las teclas -s y --short:
from django.core.management.base import BaseCommand class Command(BaseCommand): help = 'The Zen of Python' def handle(self, *args, **options): if options['short']: import __hello__ else: import this def add_arguments(self, parser): parser.add_argument( '-s', '--short', action='store_true', default=False, help=' ' )
Este archivo imprimirá Hello world cuando se llame con el modificador -s.
$ python manage.py zen -s Hello world... (coolwriter)$ python manage.py zen The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. ...
Examinemos con más detalle cómo se especifica el análisis de los argumentos.
El analizador se hereda de argparse.ArgumentParser, y puede leer sobre los argumentos tomados por la función add_argument en la documentación de la biblioteca argparse en la documentación de Python. Los más importantes son:
nombre o banderas : nombre o lista de nombres y etiquetas. Tenemos este 'corto', '-s' y '--short'.
acción : qué hacer con el valor del argumento. Las opciones más interesantes (pero no todas) son las siguientes:
store : guardar como el valor de nuestra opción. Si se transmiten varios pares clave-valor, el valor del último
store_const : guarda el valor constante en la clave de nombre. La constante se pasa como argumento
const a la misma función add_argument.
Por ejemplo:
parser.add_argument('my_option', action='store_const', const=1234)
La función de manejo en las opciones se pasará 'my_option': 1234
store_true, store_false : casos especiales de la opción anterior. Verdadero o falso almacenado
append : el valor se agregará al final de la lista
append_const es el mismo que el anterior, pero el valor pasado al argumento
const se agrega (que puede ser cualquier objeto)
nargs es el número de argumentos. Valores posibles: entero, '?' - uno o el valor predeterminado del argumento predeterminado, '*' - tantos como hay y se recopilan en una lista, '+' - al menos uno, y si varios - se recopilan en una lista, argparse.REMAINDER - todos los argumentos restantes de la línea de comando se recopilan allí . Incompatible con action = const
Tenga en cuenta: si usa este argumento, el valor de su opción desde la línea de comando se pasará a manejar como una lista, incluso si solo hay un elemento. (En este caso, el valor predeterminado se transmite tal cual, sin conversión a la lista).
El valor predeterminado es el valor
predeterminado .
type : convierte el argumento en el tipo especificado.
elecciones : restricción de variantes del valor del argumento. Se pasa una lista de valores posibles al valor de opciones.
obligatorio es un argumento obligatorio.
ayuda : una descripción de lo que hace este argumento.
dest : si desea guardar su opción con un nombre diferente, puede especificar dest = 'my_new_name'. De lo contrario, se utilizará el nombre del argumento.
Estos argumentos se pasarán a la función de manejo como un diccionario de opciones.
Pero, ¿qué pasa si queremos pasar argumentos sin nombre para manejar?
En este caso, debe especificar en add_arguments la recepción de todos los argumentos sin nombre en la opción args. Por ejemplo, si queremos pasar varios enteros al comando:
def add_arguments(self, parser): parser.add_argument( nargs='+', type=int, dest = 'args' )
Orden de ejecución
El comando se ejecuta en el siguiente orden:
- Primero, se llama al método run_from_argv (). Este método crea un analizador a través de una llamada a create_parser, y el analizador creado agrega argumentos predeterminados (de tipo sin color), y también llama al método add_arguments, agregando así todas las opciones que creamos.
- Después de eso, se llama a la función de ejecución. Esta función realiza varias verificaciones y luego ejecuta la función de manejo. El resultado del mango se imprime en la salida estándar.
Por supuesto, cualquiera de estas funciones se puede personalizar. Por ejemplo, dibujemos el hermoso resultado de un mensaje de ayuda de varias líneas:
from argparse import RawTextHelpFormatter def create_parser(self, prog_name, subcommand): parser = super(Command, self).create_parser(prog_name, subcommand) parser.formatter_class = RawTextHelpFormatter return parser
Probablemente eso sea todo lo que se necesita para escribir comandos de administración en la mayoría de los casos.
Conclusión
El artículo no pretende ser una descripción completa de todas las posibilidades al crear comandos de administración; se describen en la documentación de Django. Los interesados pueden recurrir a
documentaciónAnalizar los argumentos de la línea de comandos allí, por desgracia, prácticamente no se revela. Aquellos que deseen sumergirse en las complejidades de este problema deben estudiar la acumulación de python.
Módulo Argparse