Kitabı oku: «Django 2», sayfa 2
Crear un entorno de desarrollo Python
Es recomendable utilizar la librería virutalenv para crear un entorno de desarrollo aislado. De esta manera podremos disponer de diferentes versiones de paquetes en los distintos proyectos en los que estemos trabajando. El uso de virutalenv también ofrece independencia de la instalación de Python que haya en nuestro propio sistema. De esta manera, también se cuenta con la ventaja de no necesitar permisos de administración para la instalación de paquetes Python. Para instalar virutalenv ejecute la siguiente instrucción en una línea de comandos:

Tras la instalación de virutalenv cree un entorno de desarrollo independiente con el comando:

Esto generará un directorio my_env/ incluido el nuevo entorno Python. Cualquier librería Python que se instale mientras el entorno virtual permanezca activo se almacenará en el directorio my_env/lib/python3.6/site-packages.
Si su sistema incluía una versión Python 2.X y ha instalado Python 3 es necesario especificar la versión a utilizar durante la creación del entorno virtual con virutalenv.
En caso de querer nuestro entorno virtual con Python 3, es necesario especificar su ubicación durante la creación del mismo. Para ello, se necesita conocer la ruta y crearlo con los siguientes comandos, respectivamente:

Para activar nuestro entorno virtual ejecute el siguiente comando:

Una vez ejecutado, el intérprete de comandos cambiará, incluyendo el nombre del entorno virtual activo entre paréntesis, como se puede apreciar a continuación:

Puede desactivar el entorno virtual en cualquier momento ejecutando el comando deactivate.
Para obtener más información sobre el funcionamiento de virtualenv visite https://virtualenv.pypa.io/en/latest/.
En cuanto a virtualenv puede utilizar la herramienta virtualenvwrapper. Esta herramienta ofrece una abstracción de virtualenv que simplifica la creación y gestión de sus entornos virtuales. Puede descargarlo desde https://virtualenvwrapper.readthedocs.io/en/latest/.
Instalar Django mediante pip
El método más recomendado para instalar Django es haciendo uso del sistema de gestión de paquetes de Python pip. Python 3.6 lleva este paquete preinstalado, pero, en caso necesario, se pueden encontrar instrucciones para su instalación en https://pip.pypa.io/en/stable/installing/.
Ejecute el siguiente comando en intérprete para instalar Django con pip:

Django quedará instalado en el directorio site-packages/ del entorno virtual que esté activo durante la instalación.
Para comprobar que Django se ha instalado correctamente arranque un intérprete de Python. Después importe el paquete recién instalado y compruebe su versión. Para ello es necesario ejecutar:

Si tras la ejecución se obtiene esta salida, Django se ha instalado correctamente.
Django puede instalarse a través de otros métodos. Puede encontrar una guía de instalación más detallada en https://docs.djangoproject.com/en/2.0/topics/install/.
Crear el primer proyecto
El primer proyecto en Django consistirá en construir un blog con toda su funcionalidad. Django ofrece, para su comodidad, un comando que crea toda la infraestructura inicial de ficheros necesaria. Para ello, ejecute el siguiente comando en el intérprete:

Esto generará un directorio de nombre mysite con toda la estructura que necesitará en su interior.
Evite nombres de proyectos que coincidan con los de paquetes que Python tiene por defecto, para que no se produzcan conflictos durante las importaciones.
La estructura de directorios que se acaba de generar es la siguiente:

Estos ficheros son:
• manage.py es un script con diferentes funcionalidades que permiten interactuar con nuestro proyecto. Es un wrapper sobre djangoadmin.py y no es necesario modificarlo.
• mysite/ es el directorio del proyecto, el cual contiene:
○ __init__.py es un fichero vacío que permite indicar a Python que mysite sea utilizado como un módulo de Python.
○ settings.py incluye la configuración y propiedades principales del proyecto.
○ urls.py es un fichero donde se definen los patrones de URL. Cada URL que aparezca apunta a una vista de la aplicación.
○ wsgi.py es la configuración para arrancar nuestro proyecto como una aplicación Web Server Gateway Interface (WSGI).
El fichero generado settings.py contiene la configuración del proyecto, incluida una configuración básica para usar la base de datos SQLite3 y una lista llamada INSTALLED_APPS. Esta lista contiene todas las aplicaciones comunes de Django que se añaden al proyecto por defecto. Más adelante, en la sección de Configuración del Proyecto, revisaremos con más detalle este listado de aplicaciones.
Para terminar la instalación del proyecto, se debe crear, en la base de datos, las tablas que necesitan las aplicaciones de la lista INSTALLED_APPS. Para ello, abra una consola y ejecute ejecutamos los siguientes comandos:

Las últimas líneas de la salida que se obtienen serán:

Las líneas previas son las migraciones de base de datos aplicadas por Django. Al aplicar las migraciones, las tablas de las aplicaciones se crean en base de datos. Descubrirá más sobre el comando de gestión migrate en la sección Crear y aplicar migraciones de este capítulo.
Arrancar el servidor de desarrollo
Django trae incorporado un servidor web ligero para ejecutar el código de manera sencilla y rápida que ahorra el tiempo de configurar un servidor de producción. El servidor de desarrollo de Django revisa los posibles cambios que haya en nuestro código y es capaz de volver a desplegarlos de manera automática tras su detección. Sin embargo, no es sensible a todos los cambios que realicemos, como por ejemplo la incorporación de un nuevo fichero en el proyecto. Por lo que para estos casos se debe de parar el servidor y volverlo a arrancar.
Para arrancar el servidor de desarrollo solo se necesita escribir desde un intérprete el siguiente comando. Es importante que se haga desde la raíz del proyecto:

La salida debería ser similar a:


Acceda a la URL http://127.0.0.1:8000/ desde un navegador. Debería ver una página similar a la siguiente, indicando que el proyecto funciona correctamente:

La imagen anterior refleja que Django está en funcionamiento. Si se mira la consola en la que se ejecuta el servidor, se puede ver una petición GET realizada por el navegador:

Esta petición HTTP es registrada por el servidor de desarrollo en la consola. Cualquier error que se produzca durante la ejecución también se verá aquí.
El servidor de desarrollo de Django admite cierta configuración. Puede indicarle un host y puerto específicos o que cargue una configuración diferente del siguiente modo:

En el caso de que disponga de diferentes entornos en los que desplegar la aplicación, es una buena práctica disponer de un fichero de configuración por entorno.
Es importante recordar que este servidor está solo pensado para su uso durante el desarrollo y que en ningún caso debe utilizarse para un entorno de producción. Para desplegar la aplicación Django en un entorno real se debe de ejecutar como una aplicación WSGI sobre un servidor web como Apache, Gunicorn o uWSGI. Puede obtener más información sobre cómo realizar esta tarea con Django en https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/.
En el capítulo 13, Lanzamiento en producción, se explica cómo configurar un entorno de producción real para sus proyectos Django.
Configuración del proyecto
Toda la configuración del proyecto se encuentra en el fichero settings.py. Por defecto, durante la creación del mismo, Django incluye en este fichero información relevante que permite arrancar el proyecto, pero en él solo hay una parte de todas las variables que puede llegar a tener. Puede encontrar información sobre todas las variables de configuración y sus posibles valores en https://docs.djangoproject.com/en/2.0/ref/settings/.
A continuación, se repasan las principales variables de configuración:
• DEBUG es una variable booleana que activa o desactiva el modo de depuración en nuestro proyecto. Si está activo (con valor True), Django mostrará una página de error con la traza e información de contexto en caso de excepciones no tratadas. Cuando se despliega sobre un entorno de producción esta variable debe tener valor False. En caso contrario, se expone información sensible del proyecto.
• ALLOWED_HOSTS no se aplica cuando DEBUG está activo o cuando se ejecutan los test. Una vez se mueva el proyecto a un entorno de producción y se desactive la variable DEBUG, se deberá también añadir un dominio o host para poder servir la aplicación.
• INSTALLED_APPS es una variable que será necesario modificar en todos los proyectos y contiene información de las aplicaciones que están activas para cada uno de ellos. Por defecto, Django incluye en esta variable las siguientes aplicaciones:
○ django.contrib.admin: sitio de administración
○ django.contrib.auth: aplicación de autenticación
○ django.contrib.contenttypes: aplicación para la gestión de content types
○ django.contrib.sessions: aplicación de sesiones
○ django.contrib.messages: aplicación de mensajes
○ django.contrib.staticfiles: aplicación para la gestión de contenido estático
• MIDDLEWARE es una lista que contiene las capas intermedias que se ejecutarán.
• ROOT_URLCONF identifica el módulo Python donde están definidos los patrones de URL de la aplicación.
• DATABASES es un diccionario que contiene la configuración de nuestra base de datos. Debe haber siempre una base de datos por defecto. La configuración predefinida hace uso de una base de datos SQLite3.
• LANGUAGE_CODE define el idioma por defecto para nuestro sitio web.
• USE_TZ le indica a Django que tenga en cuenta el huso horario definido en caso de estar activo. Esta variable viene activa cuando se crea el proyecto usando startproject.
Esta es una visión general de algunas de las variables de configuración más importantes. Se detallará su utilidad a lo largo de los capítulos de este libro.
Proyectos y aplicaciones
En este libro podrá encontrar muchas menciones a los términos proyecto y aplicación. En Django, un proyecto se considera una instalación Django incluyendo su configuración. Mientras que una aplicación es un conjunto de modelos, vistas, plantillas y patrones de URL con cierta entidad independiente. Las aplicaciones interactúan con el framework Django para proveer de funcionalidad específica y pueden reutilizarse en diferentes proyectos. Se puede pensar en el proyecto como el sitio web, mientras que una aplicación es un blog, una wiki, un foro o un chat, que conforman el sitio web y pueden reutilizarse a su vez en diferentes sitios web.
Crear una aplicación
Se va a crear la primera aplicación Django y construir un blog desde cero. Para ello se ejecuta, desde la raíz del proyecto, el siguiente comando:

Esto creará la estructura principal de una aplicación, que tiene la siguiente jerarquía de ficheros:

A continuación, se dispone de:
• admin.py, que es el fichero donde se registran los modelos para que sean incluidos en el sitio de administración de Django. Hacer uso del sitio de administración de Django no es obligatorio.
• apps.py, que contiene la configuración principal de la aplicación blog.
• migrations, que es un directorio que contendrá las migraciones de base de datos de la aplicación. Esto permite que Django haga un seguimiento de los cambios en los modelos de datos y que puedan sincronizarse con la base de datos de forma coherente.
• models.py, que contiene los modelos de datos de la aplicación. Toda aplicación de Django requiere de un fichero models.py, pero el fichero puede estar vacío.
• tests.py, que es donde se incluirán los test de la aplicación.
• views.py contiene la lógica de la aplicación. Cada vista recibe una petición HTTP, la procesa y devuelve una respuesta.
Esquema de datos del blog
Se va a comenzar por el diseño del esquema de datos del blog definiendo los modelos. Un modelo es una clase Python que hereda de django.db. models.Model, en la que cada atributo representa un campo de base de datos. Por cada uno de los modelos que se ha definido en el fichero models.py Django creará una tabla en la base de datos. A través de estos modelos, Django ofrece una API que permite realizar acciones sobre objetos de la base de datos de manera sencilla.
Para comenzar, se va a definir un modelo Post. Para ello se debe añadir las siguientes líneas en el fichero models.py de la aplicación blog:

Este es el modelo de datos para los artículos del blog. Los campos que se acaban de definir en el modelo son los siguientes:
• title es un campo que contiene el título del artículo y es de tipo CharField, lo que se traduce en una columna de tipo VARCHAR en la base de datos.
• slug es un campo utilizado para la generación de la URL para el artículo. Es una cadena de texto que puede estar formada por letras, números, guiones medios y/o bajos. Se utilizará este campo para construir URLs amigables y aptas para el SEO del sitio web. Se ha incluido el parámetro unique_for_date a este campo para poder añadir también a la URL la fecha de publicación del artículo. De este modo, Django prevendrá de tener múltiples artículos con el mismo slug para la misma fecha.
• author es una clave foránea que define una relación uno a muchos. De esta forma se indica a Django que un artículo está escrito por un usuario y que, a su vez, un usuario puede ser autor de muchos artículos. Django creará esta relación en la base de datos utilizando la clave primaria del modelo al que se hace referencia, en este caso, el modelo User del sistema de autenticación del framework. El parámetro on_delete especifica el comportamiento que debe tener el artículo cuando el objeto referenciado es eliminado. Esto no es específico de Django sino de la base de datos. Si se usa el valor CASCADE, al eliminar un autor se eliminarán también todos los artículos del blog asociados a este. Para el resto de opciones disponibles puede encontrar más información en https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.ForeignKey.on_delete. Para especificar el nombre de la relación inversa (de User a Post), se utiliza el parámetro related_name. Esto nos permitirá acceder de manera sencilla a los objetos desde el modelo User.
• body contiene el cuerpo del artículo. Este campo es de tipo texto, el cual se convierte en una columna TEXT en lenguaje SQL de base de datos.
• publish es un campo de tipo fecha y hora que indica el momento de publicación del artículo. Por defecto, se usa el valor now del módulo timezone de Django. Este devuelve el momento actual según el huso horario en que se haya definido nuestro proyecto.
• created, al igual que publish, es un campo de tipo fecha y hora, pero que indica el momento de creación del artículo. Haciendo uso de auto_now_add, el valor se guardará automáticamente en la creación del objeto sin tener que especificarlo de forma explícita.
• updated es también un campo de fecha y hora. Como su nombre indica, muestra el momento del último cambio que sufrió el objeto. Para ello, se emplea auto_now, que actualizará automáticamente este valor.
• status es un campo tipo texto que contendrá los estados en los que puede estar el artículo. Haciendo uso del parámetro choices se limita el valor de status a una lista finita de valores.
Django ofrece una amplia variedad de tipos de campos para construir los modelos. En https://docs.djangoproject.com/en/2.0/ref/models/fields/ se puede encontrar una lista completa de todos los que hay disponibles.
La clase Meta dentro del modelo define metadatos del propio modelo. En este caso se indica a Django que, por defecto, cuando se realice una consulta sobre este modelo en base de datos, ordene los resultados por el campo publish en orden descendente. Esto último, se especifica con el prefijo menos. De este modo, los artículos más recientes aparecerán primero.
El método __str__() es la representación legible del objeto. Django utiliza este método en múltiples lugares, entre otros, el sitio de administración.
Si ha usado Python 2.X, tenga en cuenta que en Python 3 todas las cadenas de texto son consideradas Unicode y, por tanto, solo se utiliza el método __str__(). El método __unicode__() está obsoleto.
Activar la aplicación
Para que Django tenga constancia de la aplicación y poder realizar operaciones en ella, como crear las tablas de los modelos en base de datos, es necesario activarla. Para ello, se necesita abrir el fichero settings.py e incluir blog.apps.BlogConfig en la lista INSTALLED_APPS:

La clase BlogConfig es la aplicación de configuración. Al añadirla al setting INSTALLED_APPS Django tiene constancia de la aplicación y es capaz de cargar los modelos de datos que se defina en la misma.
Crear y aplicar migraciones
Una vez creados los modelos de datos del blog, se necesita una tabla de base de datos para gestionarlos. Django incorpora un sistema de migraciones capaz de gestionar los cambios realizados en los modelos y aplicarlos sobre la base de datos. El comando migrate aplica las migraciones de todas las aplicaciones que se encuentren definidas en la variable INSTALLED_APPS, de modo que sincroniza las tablas de la base de datos con la definición de los modelos.
Lo primero que hay que hacer es crear una migración inicial para el modelo Post. Para ello, se debe ejecutar el siguiente comando:

Para el que se debería obtener la siguiente salida:

Django acaba de crear el fichero 0001_initial.py dentro del directorio migrations de la aplicación blog. Si se mira el contenido del fichero, se puede ver cómo una migración define dependencias entre migraciones y operaciones para realizar en la base de datos. Esto permite la sincronización que se mencionó antes entre la base de datos y el modelo.
A continuación, se describe el código SQL que Django ejecutará en la base de datos para crear la tabla del modelo. El comando sqlmigrate recibe el nombre de la migración y devuelve las sentencias SQL correspondientes sin llegar a ejecutarse. Utilice el siguiente comando para revisar la salida SQL de la migración anterior:

La salida debe tener el siguiente aspecto:


La salida dependerá del tipo de base de datos que se utilice. Esta ha sido generada para SQLite. Tal como se puede apreciar en el código SQL, Django genera un nombre de tabla combinando el nombre de la aplicación junto con el nombre del modelo (blog_post). Este comportamiento se puede modificar con el atributo db_table en la clase Meta del modelo. Django también crea por defecto una clave primaria por cada modelo. El campo que utiliza como clave primaria es la columna id de tipo entero con incremento automático. Django también permite modificar la clave primaria utilizando el parámetro primary_key=True en uno de los campos del modelo.
Se va a sincronizar la base de datos con el modelo. Para ello hay que aplicar las migraciones ejecutando el siguiente comando:

Se obtiene una respuesta de varias líneas, correspondiendo la última con:

Con esto se aplican las migraciones de todas las aplicaciones declaradas en INSTALLED_APPS, incluida la aplicación blog. Tras aplicar las migraciones, la base de datos refleja el estado actual de los modelos.
Si se edita el fichero models.py, añadiendo, eliminando o modificando alguno de los campos existentes, o si se añaden nuevos modelos, se deberá crear una nueva migración a través del comando makemigrations. La migración permite a Django estar al tanto de los cambios realizados en los modelos. Una vez generada la migración, se aplica para sincronizar la base de datos mediante el comando migrate.