Django en Mac OS X. Primeros pasos

Instalación de Django

Debemos tener instalado pip en Mac OS X, el cual se instala junto con Homebrew. En ese caso, instalar Django es tan sencillo como escribir la siguiente sentencia en el terminal:

$ sudo pip install Django

Después de introducir la password, se realizará la instalación que terminara con el mensaje siguiente:

Successfully installed Django-1.8.4

Otra posibilidad es emplear la siguiente expresión en la línea de comandos:

$ sudo easy_install django

tras la que aparece el siguiente mensaje al finalizar la instalación:

Finished processing dependencies for django

En cualquier caso, podemos comprobar la versión instalada mediante la siguiente sentencia en el terminal:

$ python -c "import django; print(django.get_version())"

Creación del proyecto

Para inicializar el proyecto mysite con los elementos necesarios, nos situamos en el directorio donde queremos crear el proyecto y escribimos la siguiente sentencia:

$ django-admin startproject mysite

Para los que se inician en Python a partir de PHP se debe considerar una diferencia importante respecto al lugar donde ubicaremos el código. En PHP normalmente se coloca en la carpeta raiz el servidor /public_html/ o similar. En Django se mejora la seguridad guardando el código fuera de la raíz pública.

La sentencia anterior crea una carpeta mysite con el siguiente contenido:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

Veamos que es cada uno de estos archivos:

  • manage.py: incluye las funciones para administrar el proyecto desde la línea de comandos (referencia completa).
  • mysite/ : es el directorio donde se encuentra el proyecto y su nombre será el empleado para realizar cualquier importación al mismo (ej. mysite.urls).
  • mysite/__init__.py: este archivo no tiene contenido y cumple la función de indicar a Python que el directorio donde se encuentra es un paquete Python.
  • mysite/settings.py: contiene la configuración del proyecto y tiene todas las características de un módulo Python.
  • mysite/urls.py: en este módulo se declaran todas las URLs del proyecto y viene a ser un mapa de contenidos del sitio.
  • mysite/wsgi.py: es el punto de entrada para los servidores WSGI, el estándar para Python.

Configuración de la base de datos

La configuración de la base de datos se encuentra en el módulo settings.py. Por defecto, contiene la configuración de una base de datos SQLite, incluida en Python, adecuada para el aprendizaje pero no para proyectos reales. En este caso, los datos se guardaran en un simple fichero en el directorio del proyecto. Los parámetros que definen la base de datos se encuentran en el siguiente diccionario:

DATABASES = {
	'default': {
		'ENGINE': 'django.db.backends.sqlite3',
		'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
	}
}

Para SQLite, ENGINE es django.db.backends.sqlite3. Si usamos una base de datos MySQL este parámetro será django.db.backends.mysql. Podemos encontrar parámetros análogos para PostgreSQL u Oracle.

NAME indica el nombre de la base de datos. En el caso de SQLite será el nombre del archivo, incluyendo la ruta completa en caso de que no se encuentre en el mismo directorio del proyecto.

En el caso de una base de datos MySQL en un servidor remoto debemos facilitar otra información dentro del diccionario como USER, PASSWORD, HOST y PORT.

DATABASES = {
	'default': {
		'ENGINE': 'django.db.backends.mysql',
		'NAME': 'mydatabase',
		'USER': 'mydatabaseuser',
		'PASSWORD': 'mypassword',
		'HOST': '127.0.0.1',
		'PORT': '5432',
	}
}

En settings.py podemos también encontrar la lista INSTALLED_APPS con todas las aplicaciones activas en el proyecto. Por defecto cualquier proyecto Django tiene las siguientes aplicaciones:

  • django.contrib.admin – El administrador.
  • django.contrib.auth – Sistema de autenticación.
  • django.contrib.contenttypes – Esquema de los tipos de contenido
  • django.contrib.sessions – Sistema de sesiones.
  • django.contrib.messages – Sistema de mensajes.
  • django.contrib.staticfiles – Sistema de manejo de archivos estáticos.

Cada una de estas aplicaciones requiere al menos una tabla en la base de datos, que deben crearse mediante el siguiente comando:

$ python manage.py migrate

El servidor de desarrollo

Django contiene un servidor web básico escrito en Python adecuado para las etapas de desarrollo previas a un trabajo en producción en un servidor Apache. Para verificar que dicho servidor funciona, debemos ejecutar el siguinte comandodesde el directorio mysite:

$ python manage.py runserver

Si todo funciona correctamente veremos la siguiente respuesta en la línea de comandos:

Performing system checks...

0 errors found
September 15, 2015 - 15:50:53
Django version 1.8, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Así mismo, abriendo en el navegador la URL http://127.0.0.1:8000/ veremos el resultado.

Creación de una aplicación

Dentro de un proyecto podemos encontrar diferentes aplicaciones (app) que realizan diferentes funciones dentro del mismo. Cada aplicación está contenida en una carpeta que Django crea al efecto. Las aplicaciones son exportables a otros proyectos.

Al crear una nueva aplicación, Django creará una nueva carpeta donde se encontrarán todos los archivos de la misma. En este ejemplo se creará una aplicación denominada polls (encuestas) en el directorio principal (cualquiera hubiese sido válido) mediante la siguiente sentencia:

$ python manage.py startapp polls

El contenido de la carpeta polls será el siguiente:

polls/
    __init__.py
    admin.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py

El primer paso es definir los modelos que se guardarán en el archivo models.py. Dichos modelos contienen la estructura de la base de datos y algunos metadatos.

En nuestra aplicación para realizar encuestas crearemos dos modelos: Question (pregunta) y Choice (selección). Cada modelo equivale a una tabla que está representada por una clase que a su vez es una subclase de django.db.models.Model. La clase (tabla) Question tendrá dos variables (campos), la pregunta y la fecha de publicación, que equivalen a campos de la tabla. La clase (tabla) Choice tendrá tres variables (campos): un índice que le relaciona con la pregunta, un texto y los votos que ha recibido. El archivo models.py que contiene los modelos contendrá lo siguiente:

from django.db import models

class Question(models.Model):
        question_text = models.CharField(max_length=200)
        pub_date = models.DateTimeField('date published')

class Choice(models.Model):
        question = models.ForeignKey(Question)
        choice_text = models.CharField(max_length=200)
        votes = models.IntegerField(default=0)

Vemos que cada campo se representa por una instancia de la clase Field, como son CharField para campos de caracteres o  DateTimeField para fechas. De este modo Django conoce el tipo de dato que se aloja en cada campo.

Algunas clases precisan argumentos obligatorios, como es el caso de CharField en el ejemplo, que requiere el argumento max_length, y pueden tener también argumentos opcionales.

Activación de la aplicación

El primer paso es editar el fichero settings.py para incluir la nueva aplicación dentro de la lista INSTALLED_APPS :

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',
)

A continuación debe ejecutarse el comando makemigrations para crear una migración, informando a Django de que se han realizado cambios en los modelos, en este caso añadiendo la aplicación poll. La línea de comandos sería la siguiente:

$ python manage.py makemigrations polls

El resultado será el siguiente:

Migrations for 'polls':
  0001_initial.py:
    - Create model Question
    - Create model Choice
    - Add field question to choice

Las migraciones son archivos donde se guardan los cambios a realizar. Con el comando makemigrations hemos creado la migración, pero no la hemos realizado. Para ello debe ejecutarse el comando migrate propiamente dicho:

$ python manage.py migrate

En la consola veremos las operaciones que se van realizando, que serán todas las migraciones que no se hayan realizado hasta el momento, de acuerdo a la información almacenada por Django en la tabla django_migrations.

Primeras pruebas con la API

Django proporciona una API gratuito al que podemos acceder desde el Python shell. El primer paso es invocar el shell:

$ python manage.py shell

Se incluye  manage.py para indicar a Django la ruta al archivo mysite/settings.py.

Una vez en el  shell , importamos las clases Question, Choice:

>>> from polls.models import Question, Choice

Podemos comprobar que todavía no se ha creado ningún objeto de la clase Question:

>>> Question.objects.all()

El resultado será vacío:

[]

A continuación creamos un nuevo elemento de la tabla y lo salvamos. Dado que la variable pub_date requiere la fecha y hora  actual, vamos a escribir dicho valor de acuerdo a la zona horaria. Para ello primeramente importamos la clase preinstalada timezone incluida en utils:

>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save()

Automáticamente se le ha asignado un ID que podemos visualizar:

>>> q.id
1

Puede accederse a los campos:

>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

Ahora que ya tenemos un registro en Question podemos volver a probar Question.objects.all(). El resultado ahora es:

>>> Question.objects.all()
[]

el cual indica que no está vacío pero nos da muy poca información acerca del registro. Para ello añadimos __str__() (Python 3) o __unicode__ (Python 2) a los modelos Question y Choice:

from django.db import models

class Question(models.Model):
    # ...
    def __unicode__(self):
        return self.question_text

class Choice(models.Model):
    # ...
    def __unicode__(self):
        return self.choice_text

Después de guardar este cambio, volvemos a inicializar el shell:

$ python manage.py shell

Y cargamos de nuevo los modelos:

>>> from polls.models import Question, Choice

Ahora encontramos:

>>> Question.objects.all()
[<Question: What's new?>]

Para modificar la variable:

>>> q.question_text = "What's up?"
>>> q.save()

La API de Django permite obtener información de la base de datos mediante una serie de funciones a partir de argumentos:

>>> Question.objects.filter(id=1)
[<Question: What's up?>]
>>> Question.objects.filter(question_text__startswith='What')
[<Question: What's up?>]

>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

La referencia completa de todas las funciones de la API para acceso a la base de datos puede encontrarse en la documentación de Django.

Esta guía nos da una pequeña muestra de las posibilidades de Django a través de la consola.