Cómo Crear un Programa CLI con Django 2

Algunas aplicaciones requiere realizar algunos procesos que no necesariamente necesitan una interfaz web, algunas veces necesitas ejecutar algunas tareas de mantenimiento como eliminar algunos datos o archivos que la aplicación solo necesita de forma temporal. Para este tipo de casos solo es necesario que exista un script que se pueda ejecutar desde la línea de comandos sin embargo el ODM de Django es una ventaja que siempre es bueno tener y con Django tener esta forma de aplicación con unas cuantas líneas de código.

Cómo Crear un Programa CLI con Django 2

Supondremos que ya tienes un entorno de Python 3 listo, es decir tienes un ambiente virtual de python, instalaste pip, django y las librerías que puedas requerir. Si no tienes esto te recomiendo que veas el post Python 3 y Django en Ubuntu 18.04 con Vagrant donde puedes crear un entorno de desarrollo con una máquina virtual donde tendrás tu aplicación en un servidor local.

Crearemos primero un nuevo proyecto django para usarlo como base, en este caso asumimos que python responde al comando de python 3, si no sabes cual versión tienes instalada puedes ejecutar el comando python -V y te debe mostrar una versión 3.X como se muestra en la siguiente salida de texto:

$ python -V
Python 3.6.8

Para crear el proyecto de Django ejecutamos el siguiente código en la línea de comandos:

django-admin startproject django_cli

Ahora crearemos una aplicación con Django donde haremos un scrips que funcione desde la línea de comandos y pueda utilizar los modelos (o las tablas de una base de datos mysql). Para creamos la aplicación con la siguientes líneas:

cd django_cli
python manage.py startapp cli

Antes de utilizar la aplicación vamos a crear un modelo sencillo llamado Persona donde guardaremos el nombre y la de edad en cada registro. Editamos el archivo django_cli/cli/models.py de forma que quede así:

from django.db import models

# Create your models here.

class Persona(models.Model):
	nombre = models.CharField(max_length=50, unique=True)
	edad   = models.IntegerField(default=0)

Ahora crearemos el script para ejecutarlo desde la línea de comando. Creamos una archivo llamado personas.py y estará ubicado en la carpeta de la aplicación CLI es decir en django_cli/cli/personas.py

Agrega este código a ese archivo y grábalo.

import os, sys

# This is let Django knows where to find stuff.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_cli.settings")
sys.path.append(BASE_DIR)
os.chdir(BASE_DIR)

# This is allows models to get loaded.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

#your script goes here --+
#                        |
#                        V

def start_main_function(): 
    print("Works!")

if __name__ == '__main__':
    start_main_function()

Ahora para probarlo solo tienes que ejecutarlo. Si estás ubicado en django_cli/cli lo único que tienes que hacer es ejecutar el script, pero si te encuentras en otra ruta puedes poner la ruta absoluta del script personas.py, pero ejemplo: /var/www/django/django_cli/cli/personasl.py

Al ejecutar este script te debe presentar una leyenda que dice «Works!»

Una parte importante de este pequeño script está en la línea 6 y es el segundo parámetro de la función «django_cli.settings» éste debe coincidir con el nombre del proyecto Django, si tu proyecto de llamara «recursos_humanos» entonces este parámetro debería decir «recursos_humanos.settings». Cuando esto no coincide puedes ver un error como este:

$ python personas.py 
 Traceback (most recent call last):
   File "personas.py", line 12, in 
     application = get_wsgi_application()
   File "/home/vagrant/.virtualenvs/env/lib/python3.6/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application
     django.setup(set_prefix=False)
   File "/home/vagrant/.virtualenvs/env/lib/python3.6/site-packages/django/init.py", line 19, in setup
     configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
   File "/home/vagrant/.virtualenvs/env/lib/python3.6/site-packages/django/conf/init.py", line 79, in getattr
     self._setup(name)
   File "/home/vagrant/.virtualenvs/env/lib/python3.6/site-packages/django/conf/init.py", line 66, in _setup
     self._wrapped = Settings(settings_module)
   File "/home/vagrant/.virtualenvs/env/lib/python3.6/site-packages/django/conf/init.py", line 157, in init
     mod = importlib.import_module(self.SETTINGS_MODULE)
   File "/home/vagrant/.virtualenvs/env/lib/python3.6/importlib/init.py", line 126, in import_module
     return _bootstrap._gcd_import(name[level:], package, level)
   File "", line 994, in _gcd_import
   File "", line 971, in _find_and_load
   File "", line 941, in _find_and_load_unlocked
   File "", line 219, in _call_with_frames_removed
   File "", line 994, in _gcd_import
   File "", line 971, in _find_and_load
   File "", line 953, in _find_and_load_unlocked
 ModuleNotFoundError: No module named 'recursos_humanos'

Para solucionarlo debes asegurarte que el nombre de tu proyecto (el directorio que contiene todo el código de django) coincida con el nombre que está en el segundo parámetro de la función os.environ.setdefault(«DJANGO_SETTINGS_MODULE», «django_cli.settings»).

Trabajando con el Modelo desde la línea de comandos

En la sección anterior creamos un Modelo llamado Persona para guardar datos como el Nombre y la Edad. Ahora vamos a crear el código para acceder a la base de datos, agregar datos y listarlos.

Para asegurarnos que el modelo esté implementado debemos ejecutar:

python manage.py makemigrations
python manage.py migrate

Ahora agregaremos código para acceder a la base de datos por medio del modelo. Para hacer un ejemplo sencillo vamos a listar los registros almacenados en la tabla Persona, si está vacío agregaremos los datos «Anónimo» y con edad 99.

Primero debemos importar el modelo que vamos a utilizar, es decir el modelo Persona que creamos en el archivo django_cli/cli/models.py. Esto lo hacemos insertando esta línea:

from cli.models import Persona

Y agregamos el código para usar el modelo o los datos de la tabla.

def start_main_function():
    # Look for all records on Persona Model
    personas = Persona.objects.all()

    if not personas :
        # No records, create a new
        print("No hay Personas que listar")
        nueva = Persona()
        nueva.nombre = "Anónimo"
        nueva.edad   = 99
        nueva.save()
        print("Se ha agregado a Anónimo de 99 años")
    else:
        # List all records on Model
        for persona in personas:
            print(persona.nombre, persona.edad)

Este código agrega una persona de que llamaremos Anónimo con 99 como edad si es que la tabla personas está vacía y en caso contrario listará los registros que se encuentren.

Ahora podríamos agregar una persona tecleado el nombre y la edad como parámetros al ejecutar el script. Para esta tarea agregamos este código a la función.

    # count the arguments
    arguments = len(sys.argv) - 1

    # if there are argument ad a Persona
    if arguments > 0:
        nombre = sys.argv[1]
        edad   = sys.argv[2]
        # validate parameters to match a string and a numeric string
        if isinstance(nombre, str) and edad.isnumeric():
            # Create a new record on Model and save data on it
            nueva = Persona()
            nueva.nombre = nombre
            nueva.edad   = edad
            nueva.save()

Al recibir dos parámetros que se validan como una cadena de caracteres (o string) y un cadena numérica se agrega un registro con esta información y se lista el total de personas en la tabla. Aquí el ejemplo:

Crear un script o aplicación con Django que funcione en la línea de comandos o en la terminal es posible, incluso si necesitas acceder a una base de datos. Django te permite usar su poderoso ORM para manejar Bases de datos donde creas un modelo y puede operar con distinta bases de datos como son: Mysql/MariaDB, sqlite, PostgreSQL, Oracle entre otras y puedes usar el mismo código para cualquiera que uses y todo esto lo puedes usar en una aplicación de texto o aplicación cli.

Puedes ver el contenido de este pequeño proyecto en Github

https://github.com/larmedina75/django_cli

Si tienes cualquier duda o comentario por favor deja un comentario abajo, trataré de responderte en cuanto me sea posible.

Te dejo el código completo del script Django que funciona en la línea de comandos o terminal.

import os, sys

# This is let Django knows where to find stuff.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_cli.settings")
sys.path.append(BASE_DIR)
os.chdir(BASE_DIR)

# This is allows models to get loaded.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

#your script goes here --+
#                        |
#                        V

from cli.models import Persona

def start_main_function():
    # count the arguments
    arguments = len(sys.argv) - 1

    # if there are argument ad a Persona
    if arguments > 0:
        nombre = sys.argv[1]
        edad   = sys.argv[2]
        # validate parameters to match a string and a numeric string
        if isinstance(nombre, str) and edad.isnumeric():
            # Create a new record on Model and save data on it
            nueva = Persona()
            nueva.nombre = nombre
            nueva.edad   = edad
            nueva.save()

    # Look for all records on Persona Model
    personas = Persona.objects.all()

    if not personas :
        # No records, create a new
        print("No hay Personas que listar")
        nueva = Persona()
        nueva.nombre = "Anónimo"
        nueva.edad   = 99
        nueva.save()
        print("Se ha agregado a Anónimo de 99 años")
    else:
        # List all records on Model
        for persona in personas:
            print(persona.nombre, persona.edad)


if __name__ == '__main__':
    start_main_function()

This entry was posted in Python and tagged , , , . Bookmark the permalink.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *


*


Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.