santi@zenbook:$ python
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> |
Para salir del intérprete bastará con ejecuta la orden ''quit()''
> Hay una [[apuntes:python|guía de Python]] en la sección //Anexos// a la que habrá que echarle un vistazo antes de seguir, puesto que a partir de ahora tendremos que programar en este lenguaje.
==== Instalación de Django ====
Para la instalación de Django necesitamos la utilidad //pip// (gestor de de instalación de paquetes para Python) pero viene de serie en las versiones de Python >= 3.4 por lo que no será necesario hacer nada. Directamente podremos usarla para que se encargue de instalarnos el nuevo framework con el siguiente comando:
santi@zenbook:$ pip install django==1.11.8
Para comprobar que todo está funcionando correctamente podemos ejecutar la consola de Python y comprobar que versión del framework se ha instalado
santi@zenbook:$ python
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> print(django.get_version())
1.11.4
===== Introducción =====
Como se ha dicho anteriormente, el desarrollo en Django se realiza siguiendo una arquitectura MVC, aunque más concretamente en este caso se trabaja bajo lo que se conoce como arquitectura MVT (Model-View-Template) que sigue, en el caso de Django, al siguiente esquema:
En el esquema se pueden distinguir los diferentes componentes que formarán cualquier aplicación web desarrollada con este framework y que son las siguientes:
* **Routing (urls)**: Es un fichero que contendrá las
* **View**:
* **Template**:
* **Model**: Representa qué forma tienen la información que gestiona nuestra aplicación. Serán las clases Python que definen la estructura de la Base de Datos donde se almacena dicha información
===== Crear un proyecto y la primera aplicación =====
==== Crear un proyecto ====
Django no sólo es una conjunto de librerías de código escrito en Python sino que además dispone de una serie de comandos que pueden hacer trabajo por nosotros.
En el caso de que tengamos que iniciar un nuevo proyecto desde cero, disponemos de un comando que nos creará todas la estructura y ficheros necesarios (con el código correspondiente) para poder empezar a trabajar sin que tengamos que realizar esa tarea manualmente y de forma repetitiva cada vez que queramos empezar cada proyecto.
Asi, con el siguiente comando del framework, lanzándolo directamente desde la consola de comandos, se creará una carpeta 'peliculas' con la estructura inicial de un proyecto de Django
santi@zenbook:$ django-admin startproject peliculas
En la imagen anterior se puede observar como queda la estructura del proyecto inicial. A partir de ahora podemos decidir trabajar con el editor de código que más nos guste. En este caso la captura corresponde al editor que usaremos nosotros que es //PyCharm//. Entre los ficheros que ya aparecen creados podemos destacar los siguientes:
* **
santi@zenbook:$ python3 manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
August 31, 2017 - 13:42:42
Django version 1.11.4, using settings 'peliculas.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Y si todo funciona correctamente veremos un mensaje parecido al que se muestra justo encima.
Hay que tener en cuenta que se trata de un servidor de pruebas, para que podamos ir probando el proyecto durante el desarrollo del mismo. El despliegue de una aplicación es a veces un proceso largo y realizar dicho despliegue cada vez que se quiere probar una nueva funcionalidad puede resultar una pérdida de tiempo. De esta manera podemos probar rapidamente nuestra aplicación pero deberemos desplegar la misma de la forma correcta utilizando algún servidor más robusto si la queremos poner en marcha para producción.
==== Añadir aplicaciones a un proyecto ====
santi@zenbook:$ python3 manage.py startapp mispeliculas
Por último, antes de comenzar el desarrollo de nuestra aplicación web, echaremos un vistazo al fichero ''settings.py'' donde encontraremos la opción ''INSTALLED_APPS'' con la siguiente información ya configurada:
. . .
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
. . .
Cada línea indica una aplicación que Django tiene ya preinstalada y que podremos usar más adelante. Siempre podremos eliminar aquellas que sepamos con certeza que no vamos a usar.
Lo que sí tendremos que hacer antes de continuar es indicarle a Django que queremos que inicialize dichas aplicaciones y lo haremos con el siguiente comando, que basicamente lo que hace es crear las Bases de Datos que requieran las aplicaciones instaladas en el proyecto.
Así, ejecutaremos el siguiente comando antes de continuar, obteniendo la correspondiente salida por pantalla:
santi@zenbook:$ python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, 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 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 sessions.0001_initial... OK
Ahora ya estamos listos para empezar a trabajar en la aplicación web cuya estructura se ha generado anteriormente.
===== Definir el modelo y configurar la Base de Datos =====
Antes de definir el modelo mediante clases Python, tenemos que configurar el proyecto para que pueda hacer uso de algún motor de Bases de Datos. Para este ejemplo dejaremos la configuración como está, de forma que se utilizará el motor de SQLite tal y como muesra el parámetro ''ENGINE'' en la opción ''DATABASES'' del fragmento del fichero de configuración ''settings.py'' que se muestra a continuación. Allí también se indica el nombre del fichero que tendrá en este caso la Bases de Datos.
Si empleamos algún otro motor como MySQL o PostgreSQL tendremos que indicar los parámetros que corresponda en estos casos (como host, usuario, contraseña, . . .).
Además, tenemos que añadir nuestra aplicación ''mispeliculas'' a la lista de aplicaciones disponibles en este proyecto, tal y como aparece en la opción ''INSTALLED_APPS''.
from django.db import models
class Pelicula(models.Model):
titulo = models.CharField(max_length=200)
genero = models.CharField(max_length=200)
director = models.CharField(max_length=200, blank=True)
fecha = models.DateField
descargada = models.BooleanField(default=False, blank=True)
def __str__(self):
return self.titulo
class Serie(models.Model):
titulo = models.CharField(max_length=200)
genero = models.CharField(max_length=200)
fecha = models.DateField
temporadas = models.IntegerField(default=1)
completada = models.BooleanField(default=False)
descargada = models.BooleanField(default=False)
def __str__(self):
return self.titulo
class Capitulo(models.Model):
numero = models.IntegerField(default=0)
temporada = models.IntegerField(default=0)
serie = models.ForeignKey(Serie, on_delete=models.CASCADE)
fecha_emision = models.DateField
def __str__(self):
return self.serie.titulo + " " + self.temporada + "x" + self.numero
Una vez escritas las clases ejecutaremos el siguiente comando para indicarle que se han producido cambios en nuestro modelo (en este caso se ha creado por primera vez) y que prepare los cambios necesarios sobre la Base de Datos (todavía no los ejecuta).
santi@zenbook:$ python3 manage.py makemigrations mispeliculas
Migrations for 'mispeliculas':
mispeliculas/migrations/0001_initial.py:
- Create model Pelicula
- Create model Serie
- Create model Capitulo
- Add field serie to capitulo
Y para lanzar esos cambios sobre la Base de Datos tenemos que lanzar el comando ''migrate'' que veremos más adelante. Antes, conviene saber que siempre que queramos podremos ejecutar un comando si queremos revisar el código ''SQL'' que Django ha preparado. Este comando no tiene efecto ninguno ni realiza cambios en la Base de Datos, simplemente imprime por pantalla el código SQL del cambio que hemos dejado listo con el comando anterior.
santi@zenbook:$ python3 manage.py sqlmigrate mispeliculas 0001
BEGIN;
--
-- Create model Serie
--
CREATE TABLE "mispeliculas_serie" (
"id" serial NOT NULL PRIMARY KEY,
"titulo" varchar(200) NOT NULL,
"genero" varchar(200) NOT NULL,
. . .
. . .
);
--
-- Create model Pelicula
--
CREATE TABLE "mispeliculas_pelicula" (
"id" serial NOT NULL PRIMARY KEY,
"titulo" varchar(200) NOT NULL,
. . .
. . .
);
. . .
. . .
Hay que tener en cuenta también que este paso no es obligatorio llevarlo a cabo. Siempre podremos ejecutar el comando ''makemigrations'' y ''migrate'' seguidos //confiando// en que Django haga correctamente su trabajo.
santi@zenbook:$ python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, mispeliculas, sessions
Running migrations:
Rendering model states... DONE
Applying mispeliculas.0001_initial... OK
Además, si queremos trabajar con otro SGBD, como por ejemplo MySQL, simplemente tendremos que cambiar la configuración de conexión con la Base de Datos y crear (''makemigrations'') y lanzar (''migrate'') los cambios para que éstos sean efectivos.
. . .
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'nombre',
'USER': 'usuario',
'PASSWORD': 'contraseña',
'HOST': 'localhost',
'PORT': '3306',
}
}
. . .
==== Realizar cambios en el modelo durante el desarrollo ====
Y siguiendo con lo que contabamos en el apartado anterior a la hora de crear nuestro modelo por primera vez, cada vez que realicemos algún cambio bastará con ejecutar los comandos ''makemigrations'' y ''migrate'' y los cambios se prepararán y ejecutarán sobre la Base de Datos, respectivamente.
santi@zenbook:$ python3 manage.py makemigrations mispeliculas
. . .
. . .
santi@zenbook:$ python3 manage.py migrate
. . .
. . .
==== Probar nuestro modelo ====
En cualquier momento podemos lanzar, desde la termina, una consola interactiva de Python sobre nuestra aplicación web.
santi@zenbook:$ python3 manage.py shell
Una vez iniciada la consola, disponemos de los modelos definidos en nuestra aplicación web Django para interactuar con ellos y comprobar rapidamente si todo funciona como esperamos que lo haga. Podemos registrar objetos en la Base de Datos, consultarlos, eliminarnos, modificarlos, . . .
>>> from peliculas.models import Pelicula
. . .
>>> # Registra una pelicula en la Base de Datos
>>> pelicula = Pelicula(titulo='Rocky', director='Silvester Stallone')
>>> pelicula.save()
>>> # Lista todas las peliculas
>>> lista_peliculas = Pelicula.objects.all()
>>> print(lista_peliculas)
. . .
>>> # Obtiene una pelicula concreta por titulo
>>> pelicula = Pelicula.objects.get(titulo='Rocky')
>>> print(pelicula.titulo)
. . .
>>> # Elimina una pelicula de la Base de Datos
>>> pelicula = Pelicula.objects.get(titulo='Rocky')
>>> pelicula.delete()
. . .
>>> # Modifica datos de una pelicula
>>> pelicula = Pelicula.objects.get(titulo='Rocky')
>>> pelicula.director = 'Otro'
>>> pelicula.save()
. . .
>>> # Obtiene las peliculas ordenadas por un campo
>>> peliculas = Pelicula.objects.order_by('titulo')
>>> print(peliculas)
. . .
Django dispone de una API muy completa en relación al [[https://docs.djangoproject.com/en/2.0/ref/models/querysets/|API de consultas]] donde se pueden ver numerosos ejemplos de las diferentes vías de las disponemos para consultar y trabajar con la Base de Datos en nuestras aplicaciones web.
==== El panel de administración de Django ====
Por defecto //Django// proporciona un panel de administración para nuestra aplicación web y éste viene preparado para ser instalado en el fichero ''setttings.py''. Simplemente tenemos que crear el primer usuario administrador con el siguiente comando:
santi@zenbook:$ python3 manage.py createsuperuser
Lanzar el servidor de pruebas:
santi@zenbook:$ python3 manage.py runserver
Y podemos acceder al mismo a través de la URL ''http://localhost:8000/admin''.
Por defecto tendremos acceso a la gestión de usuarios y grupos de dicho panel. Si queremos además poder gestionar los diferentes objetos que hemos definidos como modelos de nuestra Base de Datos, tendremos que indicarlo como tal en el fichero ''admin.py'' que podemos encontrar en la carpeta de nuestra aplicación.
from django.contrib import admin
from .models import Pelicula, Serie, Capitulo
admin.site.register(Pelicula)
admin.site.register(Serie)
admin.site.register(Capitulo)
Y de esa manera podremos realizar las operaciones ''CRUD'' sobre los tres objetos definidos (en este caso) desde un panel ya creado por el propio framework.
===== Creación de vistas y templates =====
Para la creación de las vistas de nuestra aplicación utilizaremos directamente el sistema de plantillas (//templates//) que incluye el framework.
Lo primero que haremos será definir una plantilla que será donde escribiremos el código HTML que defina la estructura de la vista. Además, podremos acceder a la información que pasemos desde el código Python a dicha vista.
En el siguiente ejemplo hemos preparado una plantilla donde se listan todas las películas de la Base de Datos. Se espera una variable ''lista_peliculas'' con toda la información, que habremos pasado al cargar la plantilla.
En este caso además se trata de la página que hará de portada de nuestra aplicación (''index.html'') por lo que la asociaremos con la vista index que luego más adelante tendremos que registrar en la aplicación para definir a través de que URL podremos acceder.
Antes de seguir tendremos que crear la carpeta ''templates'' dentro de la carpeta de nuestra aplicación y a continuación otra carpeta dentro de éste con el nombre de la misma (''mispeliculas''), quedando la ruta ''templates/mispeliculas'' (en este caso). Será allí donde almacenaremos todas las plantillas de la aplicación.
Ahora definimos la plantilla en la que aparecerá el listado de peliculas mostrando el título para cada una de ellas y creándose un hipervínculo a través del ''id'' de la misma a otra ''view'' donde podríamos hacer que se mostraran los detalles de cada una:
No hay películas disponibles
{% endif %}
from django.shortcuts import render
. . .
def index(request):
lista_peliculas = Pelicula.objects.all()
contexto = {'lista_peliculas': lista_peliculas}
return render(request, 'mispeliculas/index.html', contexto)
Por último, tenemos que registrar la URL que le queramos definir a esta vista. Para eso, creamos el fichero ''urls.py'' en nuestra aplicación (por ser la primera vista que hemos creado, a partir de aquí será añadir sobre este mismo fichero) y definimos la URL para acceder a la portada:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index')
]
Y a continuación añadimos el contenido de este fichero al fichero ''urls.py'' del proyecto. A estas alturas, y puesto que ya deberíamos tener el panel de administración activado, este fichero debería quedar de la siguiente manera:
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^peliculas/', include('mispeliculas.urls')),
url(r'^admin/', admin.site.urls),
]
Así, si accedemos a la URL ''http://localhost:8000/peliculas'' se cargará la vista definida como ''index'' utilizando la plantilla que hemos escrito.
Y a continuación, podemos preparar la view y plantilla para ver el detalle de cada una de las películas. La view quedaría de la siguiente manera, definida en el fichero ''views.py''
. . .
def get_pelicula(request, pelicula_id):
try:
pelicula = Pelicula.objects.get(pk=pelicula_id)
except Pelicula.DoesNotExist:
raise Http404("La pelicula no existe")
contexto = {'pelicula': pelicula}
return render(request, 'mispeliculas/pelicula.html', contexto)
. . .
Y la plantilla quedaría asi:
{{ pelicula.titulo }}
{{ pelicula.director }}
{{ pelicula.genero }}
Y por último, añadir la url en el fichero ''urls.py'' de la aplicación ''mispeliculas'':
. . .
url(r'^peliculas/(?P[0-9]+)/$', views.get_pelicula, name='peliculas'),
. . .
Y ahora, podríamos modificar la plantilla ''index.html'' para que el título de cada película sea un enlace a esta nueva ''view'' donde podamos ver los detalles de la misma:
No hay películas disponibles
{% endif %}
{% load static %}
. . .
. . .
. . .
==== Incluir código HTML en una plantilla =====
También es posible formar una plantilla a partir del código HTML incluido en otras, como en el siguiente ejemplo que se adjunta donde se suponen una serie de documentos HTML que forman cabecera y pie de las plantillas de la aplicación web.
Además, si el caso lo requiere es posible parametrizarlas pasando parámetros a las plantillas con la orden ''with'' de forma que éstos podrán ser utilizados en la plantilla destino (con la notación ''
{% include 'peliculas/cabecera.html' %}
{% include 'peliculas/navbar.html' with titulo='Portada' %}
. . .
Esta es la página principal de mi aplicación web
. . .
{% include 'peliculas/pie.html' %}
==== Creación de formularios ====
Primero definimos el formulario en Django (crearemos el fichero ''forms.py'' por ser el primero formulario que realizamos. A partir de ahora añadiremos clases aqui para ir registrando más formularios):
. . .
{% load widget_tweaks %}
. . .
{% render_field form.titulo class="form-control" placeholder=form.titulo.label size="40" %}
{{ form.titulo.errors }}
. . .
A continuación creamos la ''view'' y ''url'' que permitan recoger los datos del formulario y registrar la pelicula en la Base de Datos:
. . .
from django.contrib import messages
. . .
messages.success(request, 'Pelicula registrada correctamente')
return redirect('nueva_pelicula')
. . .
Y ahora, en la plantilla que carga la //view// ''nueva_pelicula'' (''nueva.pelicula.html'') podremos leer ese mensaje para utilizarlo siempre y cuando no haya ningún problema al procesar el formulario:
. . .
{% if messages %}
{% for message in messages %}
{{ message }}
{% endfor %}
{% endif %}
. . .
=== Subir imágenes en un formulario ===
En el caso de que queramos subir imágenes en un formulario, tendremos que añadir algo de código adicional a lo que ya hemos comentado. A parte de definir el formulario para que soporte la subida de ficheros binarios, a la hora de definir el modelo, los campos que contenga imágenes tendrán que definirse de la siguiente forma:
. . .
. . .
El campo imagen en el modelo quedaría como sigue (hay que tener que en cuenta que tendremos que instalar el paquete ''Pillow'' si no lo tenemos ya instalado. Lo podemos hacer desde la ventana donde instalamos el paquete para ''Django'' en su día)
. . .
. . .
Por último, tendremos que definir el valor de la variable ''MEDIA_ROOT'' en el fichero ''settings.py'' de nuestro proyecto indicando la ruta (desde la aplicación web) donde se encuentra la carpeta ''img'' donde se guardan las imágenes.
No hay películas disponibles
{% endif %}Mostrando {{ peliculas.number }} de {{ peliculas.paginator.num_pages }}
. . .
santi@zenbook:$ python3 manager.py shell
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('santi', 'santi@codeandcoke.com', 'mipassword')
>>> user.save()
==== Inicio de sesión ====
A continuación, crearíamos un formulario para realizar el inicio de sesión y añadiríamos la correspondiente ''view'' y ''url'' como siempre para hacerlo funcionar. En este caso, además habría que preparar la view ''login_view'' que es donde se procesará dicho formulario para llevar a cabo la autenticación del usuario, que es en lo que nos centraremos en este apartado.
. . .
Bienvenido {{ request.user.username }}
. . .
==== Finalizar la sesión del usuario ====
Cuando queramos finalizar la sesión del usuario, simplemente tendremos que crear una view con el siguiente código:
santi@zenbook:$ pip3 install reportlab
A continuación se muestran algunos ejemplos de uso de esta librería para la generación de informes. Conviene tener en cuenta que en éstos, se muestra solamente el código corresponde a la función que permite crear la ''view'' que lanzará el informe al usuario. Faltaría registrar la correspondiente url en el fichero ''urls.py'' de nuestra aplicación web y también añadir un enlace o botón en la plantilla donde queramos que el usuario tenga que pinchar para visualizar este informe.
En este primer ejemplo se creará un informe (en PDF) donde se mostrará un título y a continuación un listado con los títulos de todas las películas de la Base de Datos. En este caso utilizaremos el objeto ''Canvas'' que nos permite ubicar los elementos del informe utilizando las coordenadas x e y para situarlos. Hay que tener en cuenta que la esquina inferior izquierda se corresponde con los valores ''x=0'' e ''y=0''.
. . .
def informe_peliculas(request):
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="peliculas.pdf"'
buffer = BytesIO()
can = canvas.Canvas(buffer)
can.drawString(200, 800, "Peliculas")
peliculas = Pelicula.objects.all()
y = 700
for pelicula in peliculas:
can.drawString(50, y, pelicula.titulo)
y -= 20
can.showPage()
can.save()
pdf = buffer.getvalue()
buffer.close()
response.write(pdf)
return response
. . .
En este segundo ejemplo, utilizando en este caso el objeto ''SimpleDocTemplate'', que permite añadir contenido al documento del informe si necesidad de indicar las coordenadas explicitamente. En este caso se genera una tabla (con borde) con el listado de las películas y cierta información sobre las mismas.
. . .
def informe_peliculas(request):
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="peliculas.pdf"'
buffer = BytesIO()
documento = SimpleDocTemplate(buffer, pagesize=A4, rigthMargin=40, leftMargin=40, topMargin=60, bootomMargin=18)
contenido = []
estilos = getSampleStyleSheet()
cabecera = Paragraph("Listado de Películas", estilos['Heading1'])
contenido.append(cabecera)
cabecera_tabla = ('Título', 'Género', 'Director')
datos = [(pelicula.titulo, pelicula.genero, pelicula.director) for pelicula in Pelicula.objects.all()]
tabla = Table([cabecera_tabla] + datos)
tabla.setStyle(TableStyle([('GRID', (0, 0), (-1, -1), 1, colors.black),]))
contenido.append(tabla)
documento.build(contenido)
response.write(buffer.getvalue())
buffer.close()
return response
. . .
Podéis encontrar más información en esta [[https://www.reportlab.com/docs/reportlab-userguide.pdf|Guía de reportlab]]
===== Internacionalización ======
Desde el directorio raíz de la aplicación (no del proyecto), primero creamos la carpeta donde se almacenarán las traducciones para cada uno de los idiomas para los que queramos dar soporte
santi@zenbook:Projects/peliculas/mispeliculas$ mkdir locale
Si el texto va en una //template// HTML:
{% load i18n %}
. . .
{% trans "Añadir pelicula" %}
. . .
Si estamos utilizando Python como lenguaje (en una vista, por ejemplo):
from django.utils.translation import ugettext as _
. . .
mensaje = _("Añadir pelicula")
. . .
Cuando queramos crear la estructura para el soporte de un idioma determinado (dentro de la carpeta de la aplicación):
santi@zenbook:$ django-admin makemessages -l es
processing locale es
santi@zenbook:$ django-admin makemessages -l en
processing locale en
{{ django_i18n.png }}
. . .
msgid "Añadir pelicula"
msgstr "Add movie"
. . .
Y si queremos reexaminar todos los ficheros de idiomas que se hayan creado porque se han realizado cambios o se han añadido nuevos mensajes (dentro de la carpeta de la aplicación):
santi@zenbook:$ django-admin makemessages -a
Además, es posible convertir estos ficheros de texto ''.po'' en ficheros binarios ''.mo'' más optimizados para usar con ''gettext'':
santi@zenbook:$ django-admin compilemessages
===== Despliegue de aplicaciones =====
==== Utilizando WSGI con Apache ====
En este apartado veremos como desplegar una aplicación web Django con Apache usando el módulo WSGI. Para ello tendremos que realizar una serie de ajustes, instalación y configuraciones:
- Antes de comenzar, tendremos que ajustar algunos parámetros de configuración de nuestro proyecto
- Más adelante instalaremos las aplicaciones y módulos necesarios para su despliegue con Apache y crearemos el host virtual
- Para terminar tendremos que ajustar algunos permisos para que Apache pueda acceder al contenido de la aplicación web sin ningún problema.
=== Ajustar parámetros en el proyecto Django ===
Antes de comenzar, tenemos que comprobar que tenemos instalado el intérprete de Python y todos los paquetes necesarios en la máquina servidor. En nuestro caso al menos los paquetes ''django'' (en nuestro caso la versión 1.11.8), ''django-widget-tweaks'' y ''Pillow'' a través del comando ''pip3 install''
santi@zenbook:$ sudo apt-get install python3
. . .
santi@zenbook:$ sudo pip3 install django==1.11.8
. . .
santi@zenbook:$ sudo pip3 install django-widget-tweaks
. . .
santi@zenbook:$ sudo pip3 install Pillow
. . .
Lo primero que haremos será reunir todos los ficheros estáticos de la aplicación con ayuda del siguiente comando, lo que generará una carpeta ''static'' en el directorio raíz de nuestro proyecto con todo el contenido estático del mismo.
santi@zenbook:$ python3 manage.py collectstatic
. . .
. . .
543 static files copied to '/home/santi/mispeliculas.com/static'
Ahora, en el fichero ''settings.py'' de nuestro proyecto, fijaremos la nueva ruta donde se ha almacenado el contenido estático y también incluiremos la ruta raíz para el contenido que se suba con los modelos (imágenes asociadas, por ejemplo, a través de un formulario).
Si además queremos que la aplicación web pueda ser accedida remotamente tendremos que definir cuáles son los hosts permitidos.
Y por último, si suponemos que la aplicación web se encuentra en un servidor de producción, podríamos desactivar el modo ''DEBUG''
santi@zenbook:$ sudo apt-get install libapache2-mod-wsgi-py3
A continuación, activamos el módulo:
santi@zenbook:$ sudo a2enmod wsgi
Enabling module wsgi.
To activate the new configuration, you need to run:
systemctl restart apache2
Finalmente tendremos que crear un host virtual con las directivas habituales para un sitio alojado por Apache, al que añadiremos algunas específicas por tratarse de una aplicación web hecha con Python
santi@zenbook:$ sudo service apache2 restart
=== Ajustes de permisos ===
Siempre dependerá de cómo se tenga configurado en cada caso, pero conviene echar un vistazo a los permisos asignados al fichero y carpeta donde se encuentra la Base de Datos (en este caso estamos utilizando SQLite), y también a la carpeta donde se encuentra el proyecto.
santi@zenbook:$ chown :www-data /home/santi/mispeliculas.com/db.sqlite3
santi@zenbook:$ chmod 664 /home/santi/mispeliculas.com/db.sqlite3
santi@zenbook:$ chown :www-data /home/santi/mispeliculas.com
santi@zenbook:$ chmod g+w /home/santi/mispeliculas.com
También es posible que necesitemos asignar permisos de escritura en la carpeta donde se sube el contenido a través de los formularios (donde indica la variable ''MEDIA_ROOT'')
santi@zenbook:$ chown -R :www-data /home/santi/mispeliculas.com/static
santi@zenbook:$ chmod -R g+w /home/santi/mispeliculas.com/static
Y ahora podrás visitar tu aplicación web Django accediendo directamente a ''http://mispeliculas.com''
==== Desplegar la aplicación utilizando entornos virtuales ====
santi@zenbook:$ pip3 install virtualenv
santi@zenbook:$ virtualenv env
santi@zenbook:$ source env/bin/activate
. . .
santi@zenbook:$ pip install django
santi@zenbook:$ pip install Pillow
. . .
santi@zenbook:$ deactivate