Un vistazo a Django Web Framework

2
44741

0. Índice de contenidos.

1. Introducción

En este tutorial vamos a ver un introducción, de forma práctica, al framework Django para desarrollo de aplicaciones web. Django es la alternativa en Python a frameworks como Spring Roo (Java), Play Framework (Java & Scala) o Ruby on Rails (Ruby).

Django es un framework de desarrollo web escrito en Python que consiste en una serie de librerías creadas con el fin de hacer el desarrollo de aplicaciones web más rápido y cómodo para los desarrolladores. Entre las facilidades que proporciona Django está la implementación de un sistema de plantillas, un ORM bastante potente, servidor para entorno de desarrollo, base de datos embebida…

Python a su vez es un lenguaje fácil de aprender, expresivo y con una sintaxis sencilla que te permitirá ponerte manos a la obra en muy poco tiempo.

2. Manos a la obra

Para seguir este tutorial necesitas:

  • Interprete de Python 2.7.x instalado.
  • virtualenv: Herramienta para crear entornos aislados en Python
  • pip: Herramienta para gestionar paquetes Python

En primer lugar vamos a crear un entorno Python aislado para nuestras pruebas con Django. Para ello ejecutaremos el comando virtualenv tutorialenv. Virtualenv creará entonces el directorio tutorialenv que tendrá la siguiente estructura:

  • bin
  • include
  • lib

De momento nos fijaremos en el directorio bin donde tenemos los ejecutables del intérprete de python, el gestor de paquetes pip y el script activate para activar el entorno virtual recién creado.
Para activar el nuevo entorno usaremos el siguiente comando source bin/activate si nos encontramos en un sistema Posix (Linux, OS X…) o ruta\a\entorno\activate si el entorno es windows.

Desde este momento nuestro entorno de ejecución Python será el entorno virtual recién creado. Las librerías que instalemos ahora serán instaladas de forma aislada a ese entorno y no de forma compartida. Para desactivar el entorno virtual tendremos que ejecutar deactivate.

Para instalar las librerías de Django vamos a usar pip, ejecutamos el comando pip install django asegurándonos de que tenemos el entorno virtual activado para descargar las librerías de Django en ese entorno. Una vez ejecutado tendremos ya instalado Django en nuestro sistema.

Para crear la estructura de nuestro proyecto, ejecutaremos el comando django-admin.py startproject tutorial. Como resultado se crearán una serie de ficheros y carpetas con la estructura y configuración básica para nuestro proyecto. Este directorio es el raiz de nuestro proyecto.

Una aplicación Django se suele organizar en módulos o miniaplicaciones más pequeñas que pueden ser reutilizables en otras proyectos. Para crear un módulo nuevo para nuestra aplicación ejecutaremos el comando django-admin.py startapp miaplicacion en el directorio raiz de nuestra aplicacion creado anteriormente ($tutorial/ de aqui en adelante).

El siguiente paso es configurar la base de datos que usaremos para persisitir nuestro modelo y registrar nuestro módulo miaplicacion como aplicación. Para ello editaremos el fichero $tutorial/tutorial/settings.py y añadimos la siguiente información: En el diccionario DATABASES añadimos la siguiente información:

  • En ENGINE configuramos el driver sqlite3 que es la base de datos embebida que viene con Django para el entorno de desarrollo
  • En NAME configuramos el fichero que contendrá nuestra base datos en forma de ruta absoluta al fichero. Es necesario que estos directorios existan. El fichero se creará una vez sincronicemos la base de datos.
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': '/Users/user/tutorial/tutorial.db',                      # Or path to database file if using sqlite3.
        # The following settings are not used with sqlite3:
        'USER': '',
        'PASSWORD': '',
        'HOST': '',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
        'PORT': '',                      # Set to empty string for default.
    }
}

Para registrar nuestro módulo como aplicación añadimos una entrada en la tupla de aplicaciones:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'miaplicacion',
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)

Como se puede intuir, por defecto Django te registra una serie de módulos, entre los que cabe destacar:

  • django.contrib.auth: Sistema de autenticación usado por Django
  • django.contrib.sessions: framework para gestionar sesiones
  • django.contrib.admin: administración de nuestro sitio web, por defecto comentado, lo descomentaremos para activarlo

Ahora podemos sincronizar por primera vez nuestra base de dato con lo que crearemos el modelo de datos base que usará Django. Ejecutamos para ello el comando $tutorial/python manage.py syncdb. Cuando nos pregunte por la creación de la creación del superuser de nuestro site respondemos que si y le damos un usuario y password. Esta operación se puede hacer más adelante tambien.

Para comprobar que todo está correctamente instalado, arrancaremos el servidor de desarrollo embebido en Django ejecutando python manage.py runserver. Si todo está bien configurado obtendremos la siguiente salida por pantalla:

Validating models...

	0 errors found
	August 29, 2013 - 06:10:26
    Django version 1.5.2, using settings 'tutorial.settings'
    Development server is running at http://127.0.0.1:8000/
    Quit the server with CONTROL-C.

Vamos a crear ahora el modelo de nuestra aplicación de ejemplo. Editamos el fichero $tutorial/miaplicacion/models.py y creamos la clase Persona:

from django.db import models

    class Persona(models.Model):
    	nombre = models.CharField(max_length=30)
        edad = models.IntegerField(default=0)
        def __unicode__(self):
        return 'Nombre: {nombre}, edad: {edad}'.format(nombre=self.nombre, edad=self.edad)

Con el código anterior, hemos creado una clase Persona que extiende de la clase Model de Django. Nuestra clase tiene dos atributos, nombre y edad. Además hemos añadido el método __unicode__ para hacer imprimible de forma legible una instancia de esa clase para posteriormente hacer pruebas con nuestro modelo desde la consola de Python. Es importante recordar tambien que en Python la indentación es muy importante.

Como nuestro modelo va a ser persistente tenemos que crear la tabla que almacenará las Personas, el ORM de Django se encarga de ello, solo tendremos que ejecutar de nuevo el comando $tutorial/python manage.py syncdb y la tabla miaplicacion_persona se creará en nuestra base de datos SQLite.

Vamos a crear ahora una plantilla que permita visualizar una lista de Personas. Para ello creamos el directorio $tutorial/miaplicacion/templates/ y dentro de él, el fichero index.html con el siguiente código:

{% if personas %}
	{% for persona in personas %}
		Nombre: {{ persona.nombre }}, edad: {{ persona.edad }}
	{% endfor %}
{% else %}
	No hay personas creadas.
{% endif %}

Para enlazar nuestra Persona (modelo) con nuestra plantilla (vista), tendremos que crear un View de Django (Controlador), existen varias formas de crear estos controladores, pero vamos a hacerlo extendiendo la clase TemplateView de Django en el fichero $tutorial/miaplicacion/:

from django.views.generic import TemplateView
from miaplicacion.models import Persona

class IndexView(TemplateView):
	template_name = "index.html"

    def get_context_data(self, **kwargs):
    	context = super(IndexView, self).get_context_data(**kwargs)
    	context['personas'] = Persona.objects.all()
        return context

Ahora tenemos que indicarle a Django la URL mediante la cual haremos accesible la vista creada, para ello creamos en nuestro módulo el fichero $tutorial/miaplicacion/urls.py y añadimos lo siguiente:

from django.conf.urls import patterns, url
from miaplicacion.views import IndexView

urlpatterns = patterns('',
	url(r'^index/', IndexView.as_view(), name='index'),
)      

y finalmente incluimos las URLs en el módulo principal del proyecto, es decir, el fichero $tutorial/tutorial/urls.py:

from django.conf.urls import include, patterns, url

urlpatterns = patterns('',
	url(r'^miaplicacion/', include('miaplicacion.urls')),
)

Como se puede comprobar, el mapeo de URLs tanto para indicar las vistas como para incluirlas de otros ficheros se hace mediante expresiones regulares, lo cual nos permite mucha flexibilidad a la hora de expresar la URL con la que hacer el matching del patrón.

Vamos a probar nuestra aplicación, para ello arrancamos de nuevo el servidor de test incluido en Django: python $tutorial/manage.py runserver asegurándonos que tenemos nuestro entorno virtual de Pyhton activado. Una vez hecho esto solamente tenemos que poner la siguiente URL en el navegador para probar nuestra vista: http://localhost:8000/miaplicacion/index

El resultado no es muy allá ya que no tenemos ningun modelo creado y por tanto el bucle for de la plantilla no se ejecuta. Vamos a añadir a continuación algunas instancias de nuestro modelo. Podemos hacer esto de varias formas, insertando directamente en la base de datos, interactuando con el shell de python y el ORM de Django, usando la consola de administración del sitio, etc…. Vamos a probar las dos ultimas:

Para usar el shell de Python y usar el API del ORM de Django ejecutaremos el comando python $tutorial/manage.py shell
e importamos nuestro modelo para crear algunas instancias y guardarlas:

>>> from miaplicacion.models import Persona
>>> persona = Persona(nombre='Homer', edad=38)
>>> persona2 = Persona(nombre='Bart', edad=10)
>>> persona.save()
>>> persona2.save()
>>> print persona
Nombre: Homer, edad: 38
>>> Persona.objects.all()
[, ]

Lo que hemos hecho aqui es crear dos instancias de la clase Persona para posteriormente guardarlas. El método save() heredado de django.db.models.Model persistirá en base de datos las instancias del modelo mediante el ORM de Django. Tambien al ejecutar la función print pasándole como argumento una instancia de Persona, se llamará al método __unicode__ implementado para tener una representación del objeto creado.

Una vez que tenemos un par de instancias creadas y guardadas, si recargamos nuestra vista en el navegador ya podemos ver que se recuperan y se ejecuta el bucle for de la plantilla creada.

Otro método para añadir instancias del modelo, es usar la consola de administración del sitio. Para habilitar la consola de administración hay que mapear la URL exactamente igual a como hicimos con nuestra vista, nuestro ficheros

$tutorial/tutorial/urls.py

contendrá entonces:

from django.conf.urls import include, patterns, url
from django.contrib import admin

admin.autodiscover()

urlpatterns = patterns('',
	url(r'^admin/', include(admin.site.urls)),
    url(r'^miaplicacion/', include('miaplicacion.urls')),
)

Fíjate que tambien se ha añadido una llamada a la función autodiscover(), esto es para automáticamente cargar los modulos admin.py de las aplicaciones instaladas (en nuestro caso la aplicación miaplicacion).

Añadimos por tanto el fichero admin.py a la aplicacion miaplicacion, es decir, en el directorio $tutorial/miaplicacion/ y escribimos lo siguiente:

from django.contrib import admin
from miaplicacion.models import Persona

admin.site.register(Persona)

Con esto registraremos nuestro modelo como gestionable desde la consola de administración.

Sólo nos queda ahora acceder a la aplicacion de administración mediante la URL http://localhost:8000/admin/ e identificarnos con el usuario creado al principio del tutorial.
Una vez dentro podremos ver nuestra aplicación (entre otras opciones) y nuestro modelo Persona. Podemos navegar por la aplicación para crear, modificar, consultar y eliminar instancias del modelo.

Hasta ahora hemos construido una aplicación muy sencilla que consulta nuestro modelo en base de datos y muestra los resultados por pantalla. Vamos a hacer nuestro ejemplo un poco más rico dando la posibilidad de crear nuevas instancias de nuestro modelo mediante un formulario simple.

Modificamos nuestra plantilla index.html para que contenga un formulario para la creación de nuevas Personas:

{% if personas %}
	{% for persona in personas %}
		Nombre: {{ persona.nombre }}, edad: {{ persona.edad }}
	{% endfor %}
{% else %}
	No hay personas creadas.
{% endif %}

{% csrf_token %}
{{ form.as_p }}

En el ejemplo usamos csrf_token para indicar que se genere un token (en un campo oculto) específico para ese envío de formulario y evitar así ataques de tipo cross site request forgery también usamos form.as_p para indicar al interprete de las plantillas que pinte cada campo del formulario dentro de un tag <p>.
Por último llamamos a la función url indicando el nombre de la URL para dar de alta la persona, así nos evitamos por URLs hardcodeadas en las plantillas.

Como siguiente paso registramos la URL de alta de persona en el fichero urls.py:

from django.conf.urls import patterns, url
from miaplicacion.views import IndexView, PersonaCrearView

urlpatterns = patterns('', 
		url(r'^index/', IndexView.as_view(), name='index'),
        url(r'^crearPersona/', PersonaCrearView.as_view(), name='crearPersona'),
)

Más adelante añadiremos la clase PersonaCrearView registrada. De momento modificamos nuestro fichero models.py para que contenga la clase que representará a nuestro formulario:

from django.db import models
from django.forms import ModelForm

class Persona(models.Model):
	nombre = models.CharField(max_length=30)
    edad = models.IntegerField(default=0)

    def __unicode__(self):
    	return 'Nombre: {nombre}, edad: {edad}'.format(nombre=self.nombre, edad=self.edad)


class PersonaForm(ModelForm):
	class Meta:
    	model = Persona
        fields = ['nombre', 'edad']

En nuestro fichero views.py añadimos la vista que procesará nuestro formulario:

from django.views.generic import TemplateView, FormView
from django.core.urlresolvers import reverse
from miaplicacion.models import Persona, PersonaForm

class IndexView(TemplateView):
	template_name = "index.html"

    def get_context_data(self, **kwargs):
    	context = super(IndexView, self).get_context_data(**kwargs)
        context['personas'] = Persona.objects.all()
        context['form'] = PersonaForm
        return context

class PersonaCrearView(FormView):
	form_class = PersonaForm

    def form_valid(self, form):
    	Persona.objects.create(
        nombre=form.cleaned_data['nombre'],
        edad=form.cleaned_data['edad'],
	)
    return super(PersonaCrearView, self).form_valid(form)

    def get_success_url(self):
    	return reverse('index')

La vista extiende de FormView, se trata de un tipo de vista especial para procesar formularios que contiene métodos para validad, redirigir el flujo una vez procesado el formulario, etc…
En esta vista especificamos mediante un atributo cual es nuestra clase que representa al formulario a procesar (PersonaForm). Cuando recibimos un formulario mediante un POST a la URL de esta vista Django llama a una serie de métodos en nuestro FormView, en ese ciclo de vida, se crea una nueva instancia del modelo Persona y posteriormente se calcula la URL a la que redirigir la petición si se procesa correctamente, esto ultimo se hace con la función reverse para calcular la URL a partir del nombre dado de alta en la configuración de URLs (fichero urls.py).

3. Conclusiones

En este tutorial hemos visto una muy breve introducción al framework Django con un ejemplo muy básico de la creación de modelos, ORM y formularios, pero la potencia de Django y el API que ofrece es muy amplio para facilitar el desarrollo rápido de aplicaciones web basadas en un patrón CRUD.
En la URL del sitio web de Django se puede encontrar información muy extensa sobre su API y las muchísimas posibilidades que ofrece.

Si quieres descargar el código, puedes hacerlo en: https://bitbucket.org/pcorujo/django-tutorial

2 COMENTARIOS

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad