django framework web python sqlite Tutorial: ¿Cómo crear tu Primera Aplicación Web usando Django? Si tienes conocimientos básicos de Python, Django es un framework para ti. Rafael Escalante · Jan 31, 2020 Durante muchos años y durante mi época como estudiante estuve aprendiendo cómo poder crear aplicaciones web de manera sencilla y con un **back-end** lo suficientemente robusto para poder realizar desde un blog hasta tareas de Machine Learning, así fue como descubrí **Django**. ## ¿Qué es Django y por qué usar Python? Django es un framework para desarrollar aplicaciones web basado en **Python**, nos permite crear aplicaciones de manera sencilla y limpia, simplemente entendiendo conocimientos básicos del protocolo **HTTP** o **HTTPS** y con un poco de conocimiento de **HTML5** podrás darles un toque personal y legible a tus aplicaciones. Una **aplicación web** puede ser desde un **blog personal** que quiero publicar en internet, una aplicación que por medio del concepto de **Machine Learning** pueda crear un **chatbot** para atender a mis clientes en un **sitio web**, hasta una aplicación que me permita llevar el manejo de inventarios en mi negocio y solo esté publicada dentro de mi red local (esto quiere decir que no es alcanzable por el **internet**. En este blog podrás seguir paso a paso ¿cómo crear una aplicación web básica?, usando Django y aplicar tus conocimientos de Python. Éste pequeño tutorial está basado en Linux, específicamente en la distribución de **Ubuntu**, si deseas correr el mismo proceso, también lo puedes hacer en Windows, instalando Python y agregando las variables globales correspondientes. También es importante aclarar que este Tutorial es para **Python3** específicamente. ## Preparando un Ambiente Virtual de Python. Entendamos como un ambiente virtual como una copia aislada de **Python** que nos permite trabajara en los objetos o dependencias de un proyecto sin necesidad de afectar otros proyectos con los cambios que se vayan a realizar, es por eso, que siempre recomiendo dar de alta un ambiente virtual por proyecto para no afectar los que estamos trabajando en otros. En este caso mi sugerencia es que creen un ambiente virtual para cada aplicación web en la que quieran trabajar. Como primer paso, vamos a instalar en nuestra máquina virtual o instancia de Ubuntu [Tutorial: ¿Cómo instalar Ubuntu Server 18.04 LTS?](http://rescalante.com/blog/kb20190604144aaebff3f6/user_guide/tutorial-como-instalar-ubuntu-server-18-04-lts) Python3 con todas sus librerías adicionales usando los siguientes comandos: ```sh sudo apt update sudo apt install python3-pip python3-dev libpq-dev ``` Ahora actualizaremos o instalaremos **pip3** que es el sistema de gestión de paquetes basados en **Python3**, en nuestro caso ya que utilizamos **Python3** usaremos los siguientes comandos: ```sh sudo -H pip3 install --upgrade pip ``` Ya que tenemos actualizado **pip** instalaremos el paquete de **Python3** que nos permite crear ambientes virtuales: ```sh sudo -H pip3 install virtualenv ``` Ahora crearemos una carpeta que puede estar localizada en donde queramos llamada **miproyecto** usando el comando **mkdir**, mi sugerencia para esta prueba es dejarla en el directorio **/home/username** que es el directorio del usuario con el que estamos trabajando en Ubuntu: ```sh mkdir miproyecto ``` Cambiamos de directorio a la carpeta **miproyecto** usando el comando **cd**: ```sh cd miproyecto ``` Finalmente creamos nuestro ambiente virtual para **Python3** usando el comando: ```sh virtualenv miproyectoenv ``` Éste comando instalará una versión de **Python3** y **pip3** aislada para que pueda trabajar en mi proyecto, siempre que quiera trabajar en el ambiente virtual de **miproyecto** puedo iniciar mi ambiente virtual con el comando: ```sh source miproyectoenv/bin/activate ``` Se activará el ambiente virtual mi proyecto, lo puedo notar por que antes de mi usuario y el nombre de mi equipo `username@hostname$` ahora aparece `(miproyectoenv) username@hostname$`, en caso de querer salirnos a continuar trabajando en Ubuntu, podemos usar el comando: ```sh deactivate ``` Lo que desactivará mi ambiente virtual, para poder continuar con este pequeño tutorial, sugiero que no desactiven su ambiente virtual ya que continuaremos trabajando con él. Es importante aclarar que dentro de nuestro ambiente virtual podemos usar los comando python y pip en lugar de **python3** y **pip3** ya que el ambiente virtual entiende que estamos trabajando en Python3. ## Instalando y configurando Django. Con nuestro ambiente virtual el listo es necesario que ahora instalemos el framework **Django** y podamos empezar a crear nuestra primera aplicación, para instalar **Django** usaremos el comando siguiente dentro de nuestro ambiente virtual: ```sh pip install django ``` Finalmente empezaremos a crear nuestro primer proyecto de **Django** usando el siguiente comando para que se cree dentro del directorio de nuestro proyecto: ```sh django-admin.py startproject miproyecto ~/miproyecto ``` Podemos notar que dentro de la carpeta mi proyecto se creó lo siguiente: * Un archivo llamando manage.py que nos ayudará a realizar diversas funciones en nuestro proyecto como empezar a correr el servidor o web o migrar las bases de datos. * En el directorio `/home/username/miproyecto/miproyecto` debemos tener los archivos **__init__.py**, **settings.py**, **urls.py** y **wsgi.py** que mas adelante explicaremos para que se usan. El primer archivo que modificaremos es el archivo `settings.py` en el cuál agregaremos parámetros de configuración necesarios para el funcionamiento de nuestra aplicación, una manera sencilla de modificar este archivo es usando el comando `nano` que nos permite modificar archivos en Linux: ```sh nano /home/username/miproyecto/miproyecto/settings.py ``` Dentro del archivo `settings.py` buscaremos la línea `ALLOWED_HOSTS` que contiene las direcciones IPv4 o Dominios de los equipos que podrán conectarse a nuestra aplicación, para fines de este tutorial se recomienda que se haga un cambio en la línea de la siguiente forma: ``` settings.py ``` ```python ALLOWED_HOSTS = ['*'] ``` Para que podamos acceder a la aplicación desde cualquier equipo de cómputo, sin embargo, en un ambiente de desarrollo real se sugiere agregar las direcciones IPv4 que tendrán acceso a la aplicación o el nombre del dominio mediante el cuál va a trabajar nuestra aplicación. Ahora buscaremos la línea `DATABASES` donde podemos observar que tenemos lo siguiente: ``` settings.py ``` ```python DATABASES = { 'default: { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } ``` En este caso **Django** por default trabaja con una base de datos de **sqlite3** si en dado momento quisiéramos usar una base de datos un poco más profesional como **postgresql** o **mysql** podemos realizar los cambios en ésta sección que queda fuera del alcance de éste tutorial, lo que sucederá con sqlite3 es que nos creará un archivo de bases de datos en el directorio de nuestro proyecto el cual se llamará `db.sqlite3` donde se contendrá toda la información de nuestro proyecto en formato SQL. Ahora buscaremos la línea `TIME_ZONE` y le diremos a nuestro proyecto que toda la información que se maneje principalmente en las bases de datos lo va a manejar con nuestro horario local, en mi caso es `America/Mexico_City`: ``` settings.py ``` ```python TIME_ZONE = 'America/Mexico_City' ``` Para poder tener un directorio donde se guardarán todos los elementos estáticos de nuestra aplicación web le diremos a nuestro proyecto de **Django** que cree una carpeta en el directorio raíz del proyecto para que los elementos estáticos como imágenes, archivos css, iconos, etc. se guarden en este directorio, para ello buscamos la línea `STATIC_URL` y debajo de la línea agregamos: ``` settings.py ``` ```python STATIC_ROOT = os.path.join(BASE_DIR, 'static/') ``` Finalmente cerramos **nano** y salvamos el archivo `settings.py` con la última modificación. ## Preparando nuestra Primera Aplicación. Aquí es donde se empieza a poner interesante puesto que la aplicación de **Django** está lista para ser montada en el servidor web, sin embargo agregando un poco más de valor a éste pequeño tutorial, vamos a agregar una aplicación a nuestro proyecto de Django, todas las configuraciones que realizamos ahora nos permitirán tener un portal de administrador y visualizar el sitio principal de Django desde nuestra aplicación web, aunque el objetivo es que podamos tener una aplicación básica, para ello crear una aplicación llamada app dentro de nuestra aplicación web de Django eso lo hacemos ejecutando el siguiente comando: ```sh python manage.py startapp app ``` Veremos que a la par de la carpeta `/home/username/miproyecto/miproyecto` se creará una carpeta llamada app en la dirección `/home/username/miproyecto/app` que contendrá lo siguiente: * Se crearán los siguientes archivos **__init__.py**, **admin.py**, **apps.py**, **models.py**, **tests.py**, **views.py** * Una carpeta llamada migrations conteniendo un archivo **__init__.py** donde se guardan todas las migraciones de las bases de datos con sus versiones. Lo primero que haremos ahora que tenemos nuestra aplicación llamada app es cambiar el directorio a `/home/username/miproyecto/app` usando el comando `cd`: ```sh cd /home/username/miproyecto/app ``` Crearemos dentro de este directorio un archivo llamando `urls.py` que nos permitirá manejar las **direcciones url** de nuestra aplicación llamada app: ```sh nano urls.py ``` Y agregaremos el siguiente contenido: ``` urls.py ``` ```python from django.urls import path, include from app.routes import personas app_name = 'app' urlpatterns = [ path('', personas.index, name='index'), ] ``` Salvamos el archivo `urls.py` con **nano**. Lo que estamos diciéndole a nuestro proyecto de **Django** es que nuestra aplicación llamada app ejecutará en la ruta principal todo el contenido de la función index que será creada más adelante en un archivo llamado `main.py`, ahora nuestro servidor con el proyecto de Django aún no está corriendo, pero más adelante se va a entender con más claridad. Ahora vamos a crear una base de datos que se encargue de manejar la información de nuestra aplicación llamada app, para ellos vamos a modificar el archivo `models.py` y crear el esqueleto para una tabla en la base de datos que nos guarde la información de Personas: ```sh nano models.py ``` Y agregaremos el siguiente contenido: ``` models.py ``` ```python from django.urls import path, include from app.routes import personas import datetime from django.db import models from django.utils import timezone class Personas(models.Model): nombre = models.TextField(null=False) apellidoPaterno = models.TextField(null=False) apellidoMaterno = models.TextField(null=False) createdAt = models.DateTimeField(auto_now_add=True) updatedAt = models.DateTimeField(auto_now=True) def __str__(self): return self.id ``` Salvamos el archivo `models.py` con nano. Ahora le estamos diciendo a la aplicación que durante la migración de la base de datos va a tomar como modelo el archivo `models.py` y creará una tabla llamada `app_personas` que tendrá las siguientes columnas: * `id` - que asignará un id único en la entrada en la base de datos. * `nombre` - que guardará la información del nombre de la persona que agreguemos. * `apellidoPaterno` - que guardará la información del apellido paterno de la persona que agreguemos. * `apellidoMaterno` - que guardará la información del apellido materno de la persona que agreguemos. * `createdAt` - guardará automáticamente la fecha y la hora de cuando se crea la entrada en la base de * datos. * `updatedAt` - guardará automáticamente la fecha y la hora de cuando se modifica la entrada en la base de datos. Para poder tener un control de las vistas en nuestra aplicación crearemos una carpeta llamada **routes** en el directorio de nuestra aplicación usando el comando `mkdir`: ```sh mkdir routes ``` Dentro de la carpeta **routes** crearemos el primer controlador de vistas, en este caso lo llamaremos personas, por lo tanto, crearemos usando nano el archivo `personas.py` (que si nos regresamos un poco antes en el tutorial los estamos importando al archivo `urls.py`) y se encargará de controlar todas las vistas que manejen algo relacionado con la tabla Personas en la base de datos: ```sh nano routes/personas.py ``` Y agregaremos el siguiente contenido: ``` personas.py ``` ```python from django.shortcuts import render, redirect from django.urls import reverse from django.conf import settings from app.models import Personas def index(request): persona = Personas.objects.create( nombre = 'John', apellidoPaterno = 'Doe', apellidoMaterno = 'Lopez' ) persona.save() query_persona = Persona.objects.get(id = 1) context = { 'persona' = query_persona } return render(request, 'index.html', context) ``` Salvamos el archivo personas.py con **nano**. Para explicar a detalle que hace el archivo personas.py es importante entender un poco del modelo cliente-servidor en el cuál usando el protocolo **HTTP** enviamos requests al servidor web a través de una url y esa url activa dentro del servidor un proceso que puede hacer diferentes funciones, que en éste caso serán nuestro código dentro de la carpeta routes, en específico hablando de `personas.py` donde tenemos una función llamada index que hará lo siguiente: 1. Creará un objeto de tipo Personas (que en realidad es el objeto que va a escribir la información a la base de datos), al cuál le estamos dando los parámetros nombre, apellidoPaterno, apellidoMaterno, es importante tomar en cuenta que la tabla personas también requiere los parámetros id, createdAt, updatedAt que se crearán automáticamente de acuerdo a la cantidad de entradas que tenga la base de datos y la fecha en la que está ocurriendo el proceso. 2. El objeto de tipo personas se guardará con el comando .save() donde le indicamos que la información se guardará en la base de datos, esto quiere decir que si abrimos nuestro archivo `db.sqlite3` encontrarás una entrada con la información de John Doe Lopez. 3. Se realizará una consulta a la base de datos con la persona que tenga el id igual a 1 4. Se enviará ese query al contexto con el nombre persona. 5. Se renderizará el archivo `index.html` con la información del contexto que se guarda en la variable context como una variable diccionario. Esto quiere decir que cada vez que haga un llamado en el navegador web a una **url** específica que definiremos en la siguiente sección ejecutará la función **index** la cuál desplegará la información en el navegador web. Dentro de la carpeta templates crearemos un archivo llamando `index.html` usando el comando nano el cuál desplegaremos a través del navegador web y representará la información que tenemos guardada en la base de datos en la entrada número 1: ```sh nano index.html ``` Y agregaremos el siguiente contenido: ``` index.html ``` ```html {% extends "layout.html" %} {% load static %} {% block content %} {{ persona.nombre }} {{ persona.apellidoPaterno }} {{ persona.apellidoMaterno }} {% endblock %} ``` Salvamos el archivo `index.html` con nano y ahora creamos un archivo llamado `layout.html` el cuál contendrá el esqueleto de nuestra aplicación web, esto es muy útil cuando quieren poner por ejemplo un menú o poner un título al código HTML y no queremos estar repitiendo el código cada vez que creemos una vista: ```sh nano layout.html ``` Y agregaremos el siguiente contenido: ``` layout.html ``` ```html Aplicación App Prueba de la Base de Datos: {% block content %} {% endblock %} ``` ## Publicando nuestra Primera Aplicación. Ahora tenemos todo listo para poder publicar nuestra aplicación en nuestra red local, para ellos hay que cambiar el directorio para regresarnos a nuestro proyecto base de **Django** usando el comando: ```sh cd /home/username/miproyecto/miproyecto ``` Para publicar nuestra aplicación llamada app tenemos que hacer un par de cambios, el primero es cambiar la url raíz modificando el archivo urls.py (que no es el mismo archivo `urls.py` que modificamos dentro de la aplicación) usando el comando nano: ```sh nano urls.py ``` Y cambiaremos el contenido por lo siguiente: ``` urls.py ``` ```python from django.contrib import admin from django.urls import include, path from app.routes import personas urlpatterns = [ path('', include('app.urls')), ] ``` Lo que hacemos cambiando este archivo es diciéndole a **Django** que queremos publicar nuestra aplicación llamada app en la url raíz y queremos que todas sus rutas que están en el archivo urls.py localizado en `/home/username/miproyecto/app` (el cual es diferente del archivo `urls.py` que acabamos de modificar) se puedan acceder a través de la ruta principal. Para poder incluir nuestra aplicación llamada app en el proyecto de **Django** ahora modificaremos el archivo `settings.py` usando nano: ```sh nano settings.py ``` Buscaremos la línea `INSTALLED_APPS` y agregaremos nuestra aplicación antes de la línea `django.contrib.admin` de la siguiente forma: ``` settings.py ``` ```python INSTALLED_APPS = [ from app.routes import personas urlpatterns = [ 'app.apps.AppConfig', 'django.contrib.admin' 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] ``` Salvamos el archivo `settings.py` usando nano. Nos queda finalmente migrar las bases de datos y lanzar la aplicación para que podamos acceder desde nuestro navegador web, lo que haremos ahora será cambiarnos al directorio base donde se encuentra `manage.py` y ejecutaremos las siguientes líneas de código para nuestro proyecto de **Django** que nos ayudarán a migrar las bases de datos del proyecto: ```sh cd /home/username/miproyecto python manage.py makemigrations python manage.py migrate ``` El proceso de migración consiste en crear las tablas adecuadas con las cuáles trabajará nuestro proyecto para poder guardar la información. Ahora migraremos la base de datos de la aplicación llamada **app** usando las siguientes líneas de comando: ```sh python manage.py makemigrations app ``` Las migraciones de nuestra aplicación app se crearán en la carpeta `/home/username/miproyecto/app/migrations` lo que nos permitirá llevar un control de las migraciones en archivos que se irán guardando con número secuencial, esto nos servirá en caso de que queremos regresar aun esqueleto de bases de datos anterior, simplemente con una línea de comandos regresaremos al modelo que queremos y así podremos llevar un control por versionamiento, en nuestro caso la primera migración que se creará a la cuál le llamaremos migración inicial, se nombrará `0001_initial.py` y para aplicar la migración ejecutamos el comando: ```sh python manage.py sqlmigrate app 0001 ``` Finalmente nos resta probar nuestra aplicación ejecutando la línea de comandos: ```sh python manage.py runserver 0.0.0.0:8000 ``` Si todos los elementos que cambiamos anteriormente no tienen ningún error aparecerá un mensaje en el cuál se contiene la frase: ``` Starting development server at http://127.0.0.1:8000/ ``` Felicidades has creado tu primera aplicación web en Django siguiendo estos sencillos pasos, para poder acceder a ella, desde tu navegador web si es que estás en **Ubuntu** puedes acceder al sitio `http://127.0.0.1:8000` o desde otro dispositivo de la red local a través de la dirección IPv4 que tiene tu equipo de **Ubuntu**, como por ejemplo `http://192.168.1.100:8000` Ahora solo queda pulir un poco tu interfaz de usuario basada en código **HTML**, una recomendación que te puedo hacer es utilizar la herramienta [Bootstrap](https://getbootstrap.com/) basada en el código front-end de Twitter el cuál puedes utilizar para irle dando forma a tu aplicación. Si te gustó este artículo o quieres que escriba sobre algún otro tema de tu interés, no dudes en dejarme tus comentarios.