Saltar al contenido
🐍 Curso de Python
/

Módulo 4 · Lección 7 de 45

Las aplicaciones dentro del proyecto

Por qué un proyecto de Django se parte en trozos, dónde va por fin tu código, y el olvido que no da ningún error.

⏱ 14 min de lectura

En la lección 6 escribiste una vista en el paquete de configuración, y quedó dicho que ese no era su sitio. Ahora se muda.

Las aplicaciones son la unidad en la que Django parte un proyecto, y el nombre confunde: no son programas, son carpetas con una estructura pactada. Un proyecto es un conjunto de aplicaciones, y las cuatro que vienen puestas de fábrica —la autenticación, el panel de administración, las sesiones— son aplicaciones exactamente iguales que las que vas a escribir tú.

Por qué partir el proyecto#

La razón de fondo es que Django se diseñó en un periódico, para una redacción que tenía una web de noticias, otra de clasificados y otra de eventos, y todas necesitaban lo mismo: usuarios, comentarios, etiquetas, un buscador. La idea fue que esas piezas comunes se pudieran escribir una vez y enchufar en los tres sitios.

De ahí sale la definición práctica: una aplicación es un trozo del proyecto que hace una cosa y que podrías llevarte a otro proyecto. La agenda de contactos es una. El blog de la empresa sería otra. El sistema de usuarios es otra, y esa ni la escribes tú porque viene con Django.

En un proyecto pequeño, esa capacidad de llevártela no la vas a usar nunca, y sin embargo la división sigue mereciendo la pena por lo que impone: cada aplicación tiene sus modelos, sus vistas, sus plantillas y sus pruebas en su carpeta, y cuando abras el proyecto dentro de seis meses sabrás dónde mirar.

Crearla#

bash
python manage.py startapp contactos

No imprime nada. Ha creado esto:

text
contactos/
  __init__.py       Vacío: declara que es un paquete
  apps.py           La configuración de la aplicación
  models.py         Los modelos. Bloque B
  views.py          Las vistas. Bloque C
  admin.py          Qué se registra en el panel de administración. Bloque E
  tests.py          Las pruebas. Lección 39
  migrations/       Las migraciones, de momento vacía

Casi todos nacen con un comentario dentro y nada más:

contactos/views.py
from django.shortcuts import render

# Create your views here.

La carpeta está al lado de manage.py, no dentro del paquete de configuración. Y faltan dos cosas que vas a crear a mano en cuanto hagan falta, porque startapp no las pone: urls.py, que se hace en esta misma lección, y la carpeta templates/, que llega en el bloque C.

Registrarla#

Una aplicación creada no está puesta. Hay que añadirla a INSTALLED_APPS, al final de la lista:

agenda/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'contactos',
]

Con esa línea, Django ya sabe que la aplicación existe y empieza a mirar dentro: busca sus modelos para crear las tablas, sus plantillas al renderizar, sus pruebas al ejecutar test y su admin.py al montar el panel.

Mudar la vista#

Ahora se mueve lo de la lección 6. La vista pasa a contactos/views.py, con el nombre de fichero que usa Django:

contactos/views.py
from django.http import HttpResponse


def lista(peticion):
        nombres = ["Ana Ruiz", "Luis Pardo"]
    filas = "".join(f"<li>{n}</li>" for n in nombres)
    return HttpResponse(f"<h1>Contactos</h1><ul>{filas}</ul>")

Dos cambios respecto a como estaba. El fichero se llama views.py en inglés, porque ese nombre lo impone Django en unos cuantos sitios y no es negociable como sí lo era el de vistas.py. Y la función se llama lista y no contactos, porque ya está dentro de la aplicación de contactos y repetir la palabra sobra: la dirección acabará siendo contactos.lista.

Su propio fichero de rutas#

Aquí está el reparto que hace escalable un proyecto. En vez de que el urls.py del proyecto conozca todas las direcciones, cada aplicación declara las suyas y el proyecto solo dice por dónde cuelgan.

Crea contactos/urls.py:

contactos/urls.py
from django.urls import path

from . import views

app_name = 'contactos'

urlpatterns = [
    path('', views.lista, name='lista'),
]

Y en el del proyecto, include:

agenda/urls.py
from django.contrib import admin
from django.urls import include, path

from . import vistas

urlpatterns = [
    path('', vistas.portada),
    path('contactos/', include('contactos.urls')),
    path('admin/', admin.site.urls),
]

include hace algo muy concreto: le corta a la ruta el trozo que ya ha encajado y le pasa el resto al otro fichero. Una petición a /contactos/ encaja con 'contactos/', y lo que queda es la cadena vacía, que es lo que contactos/urls.py compara con sus patrones. Por eso el patrón de dentro es '' y no 'contactos/': la aplicación no sabe ni tiene que saber bajo qué dirección la han colgado.

Esa ignorancia es justo lo que la hace reutilizable. Si mañana la agenda tiene que vivir en /agenda/personas/, se cambia una línea del proyecto y dentro de la aplicación no se toca nada.

Comprueba que sigue funcionando:

bash
curl -s http://127.0.0.1:8000/contactos/
Salida en pantalla
<h1>Contactos</h1><ul><li>Ana Ruiz</li><li>Luis Pardo</li></ul>

Lo mismo que antes, y ahora el código está donde tiene que estar. Ya puedes borrar agenda/vistas.py, dejando en el paquete de configuración solo la vista de la portada o moviéndola también a una aplicación propia.

apps.py y una sorpresa de la versión#

El fichero que menos se toca:

contactos/apps.py
from django.apps import AppConfig


class ContactosConfig(AppConfig):
        name = 'contactos'

Sirve para dos cosas. Una es ponerle un nombre legible a la aplicación, que es el que sale en el panel de administración:

python
class ContactosConfig(AppConfig):
        name = 'contactos'
    verbose_name = 'Agenda de contactos'

La otra es el método ready(), que Django llama cuando la aplicación está cargada del todo. Es el sitio correcto para las señales, y aparece en el bloque E.

Con qué criterio se parte#

La pregunta que sigue es cuántas aplicaciones hacen falta. No hay una respuesta buena, pero sí dos malas muy frecuentes.

Una es una sola aplicación para todo, normalmente llamada core o principal, con cuarenta modelos dentro. Funciona y renuncia a lo único que aportaba la división, que es saber dónde está cada cosa.

La otra es una aplicación por modelo. Se acaba con quince carpetas de tres líneas cada una, importándose entre ellas en todas las direcciones, que es peor que no haber partido nada.

El criterio que funciona es preguntarse si el trozo tiene sentido por sí solo. La agenda de contactos lo tiene: se entiende sin saber nada del resto del proyecto. Un modelo de "grupo de contacto" no lo tiene, porque solo existe para los contactos; va dentro de la misma aplicación.

Para este módulo, la agenda es una aplicación y punto. Los dos proyectos del final tendrán dos o tres, y ahí se verá el reparto con más de una pieza sobre la mesa.