Introducción a Django (2ª parte)
Estructura de una aplicación Django
Si queremos desarrollar un proyecto Django desde 0 tenemos que generar los ficheros del proyecto, para ello debemos ejecutar:
(django)$ django-admin startproject mysite
Eso creará un directorio mysite con nuestro proyecto Django que acabamos de crear.
Nosotros no vamos a ejecutar ese comando porque partimos de un proyecto Django ya construido. En nuestro caso nuestra aplicación está en el repositorio Django Guestbook: https://github.com/josedom24/guestbook_django.
La estructura general de un proyecto Django es la siguiente:
guestbook_project/
├── manage.py
├── guestbook_project/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
│ └── asgi.py
manage.py: La utilidad de terminal que vamos a usar para manejar nuestra aplicación.- El directorio
guestbook_projectes un paquete python (agrupa distintos módulos (ficheros python)). Esto se indica con un fichero vacío que se de be llamar__init__.py. settings.py: La configuración de la aplicación.urls.py: Donde se declaran las rutas que va tener la aplicación.wsgi.py: Fichero wsgi para el despliegue de la aplicación utilizando el protocolo wsgi.asgi.py: Fichero asgi para el despliegue de la aplicación utilizando el protocolo asgi.
Aplicaciones en un proyecto Django
Ya tenemos un proyecto Django construido. Ahora tenemos que darle funcionalidad. Cada una de las funcionalidades de un proyecto Django se llama aplicación. Por ejemplo un proyecto Django de gestión puede tener una aplicación de clientes, otra de pedidos, otra de presupuestos,…
Por defecto nuestro proyecto Django ya tiene algunas aplicaciones configuradas:
admin: Panel administrativo que nos permite manejar la base de datos de nuestra aplicación.auth: Aplicación que me permite trabajar con usuarios en mi proyecto.- …
Además de las aplicaciones por defecto, el programador deberá añadir las aplicaciones adicionales para que el proyecto ofrezca distintas funcionalidades. En nuestro ejemplo, tenemos una aplicación llamada guestbook que nos permite gestionar un libro de visita, donde podemos poner comentarios que se irán guardando en una base de datos. La aplicación guestbook se encuentra en el directorio guestbook:
guestbook_project/
├── manage.py
├── guestbook_project/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
│ └── asgi.py
├── guestbook/
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── models.py
│ ├── urls.py
│ ├── views.py
│ └── templates/
│ └── inicio.html
├── static/
│ └── style.css
└── requirements.txt
:::caution[Ejercicio]
- Estudia la organización de los ficheros del proyecto Django.
- Te tiene que quedar claro que los ficheros dentro del directorio
guestbook_projectson del proyecto y que los ficheros dentro deguestbookson los de la aplicación guestbook. - Si este proyecto tuviera más aplicaciones tendríamos un directorio por cada una de ellas. :::
La configuración del proyecto
Veamos el ficheros settings.py que encontramos dentro del directorio guestbook_project:
DEBUG = True: Si está activo los errores que se produzcan en la aplicación se verán con todo lujo de detalles en el navegador. Si tenemos la aplicación en producción debería serFalse.ALLOWED_HOSTS = []: Una lista con los nombres con los que se va a permitir el acceso a la aplicación.INSTALLED_APPS = [...]: La lista de las aplicaciones que tiene instalada el proyecto.DATABASES: Configuración de la base de datos que se va a utilizar en el proyecto. Por defecto se utiliza una base de datos sqlite llamadadb.sqlite3.
:::caution[Ejercicio]
- Estudia el contenido del fichero de configuración.
- Comprueba la lista de aplicaciones que tiene el proyecto.
- Comprueba que base de datos tiene definida el proyecto Django. :::
El modelo de la aplicación
Django incluye un ORM (Object Relational Mapper), un sistema que permite trabajar con la base de datos usando objetos Python en lugar de sentencias SQL.
El modelo nos permite diseñar las tablas y las relaciones con la que vamos a trabajar en nuestra aplicación. El modelo de Django nos independiza del motor de base de datos, es decir, vamos a trabajar con clases y objetos que representan los datos y nos da igual que los datos se guarden en cualquier tipo de base de datos.
El modelo de la aplicación guestbook se define en el fichero guestbook/models.py:
from django.db import models
class Entry(models.Model):
content = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.content
Cada clase representa una tabla y la definición de sus atributos.
Se crea una clase llamada Entry. Si creamos objetos de esta clase en el programa podremos gestionar los datos de una tabla dentro de la base de datos que hemos configurado en el proyecto.
La tabla tendrá tres campos:
- Un
idautoincremental, que no hemos indicado. content: Cadena de caracteres con longitud 255, donde se guarda el mensaje.created_at: De tipo fecha/Hora que guarda la fecha y la hora de creación del comentario-
Con los objetos de la clase Entry podremos insertar, modificar, eliminar, consultar, … los registros de la tabla.
¿Qué relación tiene el modelo con la base de datos que hemos configurado en el fichero settings.py?
El programa va a trabajar para gestionar los datos con los objetos de esta clase, pero cada vez que se haga una operación en los datos se traducirá internamente a SQL para que se guarde en la base de datos configurada.
:::caution[Ejercicio]
- Estudia el fichero donde está definido el modelo de la aplicación. :::
Migraciones
Las migraciones son el mecanismo mediante el cual Django traduce los modelos Python a tablas reales en la base de datos.
Tenemos que trasladar a la base de datos configurada, las tablas que hemos representado con clases en el modelo.
Para ello usamos las migraciones que son ficheros con las instrucciones necesarias para que Django pueda crear o modificar el esquema de la base de datos.
Cada una de las aplicaciones puede tener un modelo, y tendrá una migración inicial. Por ejemplo, la aplicación guestbook guarda su migración inicial en el fichero guestbook/migrations/0001_initial.py.
Para aplicar la migración inicial, y crear las distintas tablas de las distintas aplicaciones del proyecto, ejecutamos:
python3 mange.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, guestbook, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying guestbook.0001_initial... OK
Applying sessions.0001_initial... OK
A continuación podemos acceder a la base de datos y comprobar que se han creado las tablas:
sqlite3 db.sqlite3
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> .tables
auth_group django_admin_log
auth_group_permissions django_content_type
auth_permission django_migrations
auth_user django_session
auth_user_groups guestbook_entry
auth_user_user_permissions
:::caution[Ejercicio]
- Comprueba las migraciones que tiene la aplicación guestbook.
- ¿Qué función tiene la instrucción
python3 mange.py migrate?. - Instala el cliente
sqlite3y accede a la base de datos. Lista las tablas y reliaza unselectpara ver los mensajes que tienes guardados en la aplicación guestbook. :::
Modificación del modelo
Si durante el proceso de desarrollo de nuestra aplicación, el equipo de desarrollo necesita modificar el modelo de una aplicación, por ejemplo:
- Modificando la definición de una tributo.
- Introduciendo otra clase que representa una nueva tabla.
- Añadiendo un nuevo atributo.
- …
Esta modificación en el modelo habrá que traspasarla a nuestra base de datos. Necesitamos las instrucciones para que Django pueda cambiar el esquema de la base de datos, necesitamos una nueva migración.
Para que siga funcionando bien la aplicación tendremos que crear una migración:
(django)$ python3 manage.py makemigrations
Esto creará un fichero de migración en el directorio polls/migrations. Una migración es un script que al ejecutarlo se cambia la estructura de la base de datos según el cambio del modelo. Para ejecutar la migración:
(django)$ python3 manage.py migrate
Las rutas y el controlador de la aplicación
En Django, y en general en Python, cuando programamos una aplicación web, las rutas que se usan para accedr a las distintas funcionales, son rutas virtuales, no forman parte del sistema de ficheros como en PHP.
Las rutas virtuales que vamos a usar para acceder a las distintas funciones de la aplicación se definen a nivel de proyecto y a nivel de aplicación:
- A nivel de proyecto están definidas
guestbook_project/urls.py. - Dentro de cada aplicación, en nuestro caso del directorio
guestbookpuede haber otro ficherourls.pydonde se definen las rutas propias de la aplicación (en este ejemplo no existe este fichero).
Cada una de las rutas definidas en estos ficheros hacen referencia a las funciones que se ejecuta, que esstán definfidas en el fichero guestbook/views.py.
Por ejemplo en nuestro ejemplo:
-
En el fichero “guestbook_project/urls.py` nos encontramos la definición de las dos rutas siguientes:
path("", views.inicio, name="inicio"), path("add/", views.add, name="add"), -
Es decir, cuando estramos en la raíz de la aplicación, se ejecuta la función
inicioque está definida en el ficheroguestbook/views.py. -
Y cuando se accede a la ruta
add, se ejecuta la funciónadd.
Las vistas de la aplicación
Las vistas en djando se implementan usando plantillas (templates). django tiene un motor de plantillas propio. Podemos encontrar las plantillas de la aplicación en dos niveles:
- A nivel de proyecto: estarían guardadas en el directorio
guestbook_project/templates. - A nivel de aplicación: estarían guardadas en el directorio
guestbook/templates(en nuestro ejemplo no existe este directorio).
Cada una de las funciones que se definen en el fichero views.py, ejecutan un código y finalmente pueden:
-
Mostrar una página web dinámica a partir de una plantilla a la que le manda información, usando la instrucción
render. En nuestro caso, la funcióniniciomuestra una página web usando el templateinicio.htmlal que le mandamos la lista de mensajes que tenemos guardado en la base de datos:... return render(request, "inicio.html", {"noredis": noredis, "lista": [e.content for e in entries], "form": form}) -
Realizar una redirección a otra página. En nuestro ejemplo la función
addañade el mensaje del formulario a la base de datos, y posteriormente con la instrucciónredirectredirige a la función deiniciopara mostrar de nuevo la página principal.... return redirect("inicio")
Aplicación django_tutorial
Ahora vamos a trabajar con otra aplicación Django que encuentras en el repositorio https://github.com/josedom24/django_tutorial.
Esta aplicación, nos permite trabajar con encuestas. Podemos dar de alta preguntas para las encuesta e indicar las posibles respuestas para que los usuarios voten.
Esta aplicación es una variante de la aplicación que se construye en tutorial de django. Si queréis aprender un poco de django, es muy recomendable seguir el tutorial.
:::caution[Ejercicio]
- Realiza un fork del repositorio.
- Realiza los pasos necesarios para probar la aplicación en el entorno de desarrollo.
- Da de alta una encuesta en la zona de administración y comprueba la funcionalidad de la aplicación accediendo con un navegador web.
- Estudia el modelo de la aplicación y determina que tablas se van a crear y que atributos tiene cada una. ¿Existe alguna relación entre las tablas?.
- ¿Cómo se crean las tablas en la base de datos?
- Comprueba la base de datos que está configurada en el proyecto.
- Accede a la base de datos y comprueba las tablas que se han creado. realiza una consulta para seleccionar la pregunta que has creado para la encuesta. :::
Las rutas virtuales que vamos a usar para acceder a las distintas funciones de la aplicación se definen a nivel de proyecto y a nivel de aplicación:
- A nivel de proyecto estudiamos el fichero
django_tutorial/urls.py:- Donde se ha definido que cuando se acceda a la ruta
polls/se utilizaran las rutas definidas en la aplicaciónpolls. - Y cuando se acceda a la ruta
admin/se utilizarán las rutas definidas en la aplicaciónadmin(panel de administración).
- Donde se ha definido que cuando se acceda a la ruta
- A nivel de aplicación, vemos el fichero
polls/urls.pyy comprobamos que se han definido 4 rutas:- La ruta principal ”: Donde se va a ejecutar la función
index, que muestra la lista de encuestas. Ejemplo:http://localhost:8000/polls. - La ruta
<int:pk>/: Cuando se ponga un entero se mostrará información de esa encuesta. Esto se hace en la funcióndetail. Ejemplo:http://localhost:8000/polls/1/. - La ruta
'<int:pk>/results/: Donde se nos mostrará los resultados de la encuesta identificada por su código. Esto se realiza con la funciónresults. Ejemplo:http://localhost:8000/polls/1/results/. - La ruta
<int:question_id>/vote/: Nos permite votar una opción de una encuesta. Esto lo realiza la funciónvote. Por ejemplo:http://localhost:8000/polls/100/vote/.
- La ruta principal ”: Donde se va a ejecutar la función