Diferencia entre revisiones de «Curso Python DGA 2011/django/intro»

De WikiEducator
Saltar a: navegación, buscar
(Página creada con ' == Instalación == https://docs.djangoproject.com/en/1.3/intro/install/ <source lang="python"> >>> import django >>> django.VERSION (1, 3, 0, 'final', 0) </source> == Crear u…')
 
 
Línea 1: Línea 1:
 
 
== Instalación ==
 
== Instalación ==
https://docs.djangoproject.com/en/1.3/intro/install/
+
* https://docs.djangoproject.com/en/1.3/intro/install/
  
 +
* Comprobamos que está instalado (y la versión)
 
<source lang="python">
 
<source lang="python">
 
>>> import django
 
>>> import django
Línea 9: Línea 9:
 
</source>
 
</source>
  
== Crear un proyecto ==
+
== Creación de un proyecto ==
Seguimos el tutorial de django: https://docs.djangoproject.com/en/1.3/intro/tutorial01/
+
 
<source lang="python">
 
<source lang="python">
 
$ django-admin.py startproject sitio_encuestas
 
$ django-admin.py startproject sitio_encuestas
Línea 21: Línea 20:
 
</source>
 
</source>
  
 +
Un proyecto en Django son '''4 ficheros''':
 
;__init__.py
 
;__init__.py
 
: Indica que se trata de un paquete.
 
: Indica que se trata de un paquete.
Línea 30: Línea 30:
 
: Gestiona la tabla de urls a las que responde el proyecto.
 
: Gestiona la tabla de urls a las que responde el proyecto.
  
== Servidor de desarrollo ==
+
== Servidor web de desarrollo ==
Comprobamos el funcionamiento:
+
El proyecto incorpora un servidor web:  
 
<source lang="bash">
 
<source lang="bash">
 
$ cd sitio_encuestas
 
$ cd sitio_encuestas
Línea 42: Línea 42:
 
Quit the server with CONTROL-C.
 
Quit the server with CONTROL-C.
 
</source>
 
</source>
 +
 
Comprobamos la dirección con el navegador o  
 
Comprobamos la dirección con el navegador o  
 
<source lang="bash">
 
<source lang="bash">
Línea 50: Línea 51:
 
Content-Type: text/html
 
Content-Type: text/html
 
</source>
 
</source>
Este servidor ligero nos servirá para desarrollar el proyecto. No está pensado para sitios en producción.
 
 
{{Tip| Podemos cambiar el puerto ejecutando:
 
{{Tip| Podemos cambiar el puerto ejecutando:
 
   $ python manage.py runserver 8080
 
   $ python manage.py runserver 8080
Línea 56: Línea 56:
 
   $ python manage.py runserver 0.0.0.0:8000
 
   $ python manage.py runserver 0.0.0.0:8000
 
}}
 
}}
 
+
Este servidor ligero nos servirá para desarrollar el proyecto. No está pensado para sitios en producción.
 +
Para usar Django en producción, revisa la documentación: https://docs.djangoproject.com/en/1.3/howto/deployment/
  
 
== Configuración del proyecto ==
 
== Configuración del proyecto ==
 
Editar '''settings.py'''
 
Editar '''settings.py'''
Como el fichero necesita rutas absolutas, podemos añadir esta función:
+
===Rutas absolutas===
 +
Como la configuración necesita rutas absolutas, podemos añadir esta función a settings.py:
 
<source lang="python">
 
<source lang="python">
 
import os
 
import os
Línea 68: Línea 70:
  
 
=== Configuración de la base de datos===
 
=== Configuración de la base de datos===
 +
Por defecto, tiene sopote para Postgresql, MySQL, Sqlite y Oracle.
 
<source lang="python">
 
<source lang="python">
 
DATABASES = {
 
DATABASES = {
Línea 81: Línea 84:
 
</source>
 
</source>
 
Para usar sqlite:
 
Para usar sqlite:
 
 
<source lang="python">
 
<source lang="python">
 
DATABASES = {
 
DATABASES = {
Línea 90: Línea 92:
 
}
 
}
 
<source>
 
<source>
Cambiamos también otros datos:
+
Para usar otra base de datos, tenemos que configurar el servidor con una base de datos y un usuario que tenga acceso a ella.
 +
 
 +
===configuración regional===
 
<source lang="python">
 
<source lang="python">
 
TIME_ZONE = 'Europe/Madrid'
 
TIME_ZONE = 'Europe/Madrid'
Línea 96: Línea 100:
 
</source>
 
</source>
  
Ejecutamos:
+
=== Aplicar los cambios ===
 
<source lang="python">
 
<source lang="python">
 
$python manage.py syncdb
 
$python manage.py syncdb
 
</source>
 
</source>
que crea las tablas necesarias para el desarrollo de proyecto, incluyendo todas las aplicaciones incuidas en INSTALLED_APPS
+
Crea las tablas necesarias para el desarrollo de proyecto, incluyendo todas las aplicaciones incuidas en INSTALLED_APPS
  
 
==Proyectos y aplicaciones==
 
==Proyectos y aplicaciones==
 
Para optimizar los recursos, un proyecto puede tener varias aplicaciones. Estas aplicaciones se pueden instalar en varios proyectos.  
 
Para optimizar los recursos, un proyecto puede tener varias aplicaciones. Estas aplicaciones se pueden instalar en varios proyectos.  
 
Por eso se dice que las aplicaciones de django son '''"pluglables"'''.
 
Por eso se dice que las aplicaciones de django son '''"pluglables"'''.
 +
 +
=== Creación de una aplicación===
 
<source lang="python">
 
<source lang="python">
 
$ python manage.py startapp encuestas
 
$ python manage.py startapp encuestas
Línea 116: Línea 122:
 
     views.py
 
     views.py
 
</source>
 
</source>
 
+
=== Incluir la aplicación en el proyecto ===
 
Hay que añadir la nueva apliación a '''INSTALLED_APPS''' dentro de '''settings.py'''
 
Hay que añadir la nueva apliación a '''INSTALLED_APPS''' dentro de '''settings.py'''
 
<source lang="python">
 
<source lang="python">
Línea 125: Línea 131:
 
     'django.contrib.sites',
 
     'django.contrib.sites',
 
     'django.contrib.messages',
 
     'django.contrib.messages',
     'sitio_encuestas.encuestas'
+
     'sitio_encuestas.encuestas',
 
)
 
)
 
</source>
 
</source>
Línea 150: Línea 156:
 
</source>
 
</source>
  
 +
* Tipos de datos: https://docs.djangoproject.com/en/1.3/ref/models/fields/
 +
* Más opciones
 +
 +
=== Ver sql ===
 
<source lang="python">
 
<source lang="python">
 
$ python manage.py sql encuestas
 
$ python manage.py sql encuestas
Línea 172: Línea 182:
 
COMMIT;
 
COMMIT;
 
</source>
 
</source>
 +
=== Syncdb ===
 
Si el código es correcto, ejecutamos:
 
Si el código es correcto, ejecutamos:
  
Línea 190: Línea 201:
 
No fixtures found.
 
No fixtures found.
 
</source>
 
</source>
 +
Si las tablas tienen datos, ya no modificará la estructura. Soluciones: eliminar los datos de esa aplicación o usar South: http://south.aeracode.org/
  
== Jugando con el ORM de Django ==
+
== Acceso a los datos ==
 
<source lang="python">
 
<source lang="python">
 
$ python manage.py shell
 
$ python manage.py shell

Última revisión de 05:59 26 ago 2011

Instalación

  • Comprobamos que está instalado (y la versión)
>>> import django
>>> django.VERSION
(1, 3, 0, 'final', 0)

Creación de un proyecto

$ django-admin.py startproject sitio_encuestas
$ ls -l
sitio_encuestas/
    __init__.py
    manage.py
    settings.py
    urls.py

Un proyecto en Django son 4 ficheros:

__init__.py
Indica que se trata de un paquete.
manage.py
Programa de gestión de django. A partir de ahora será el que usemos para interactuar con el proyecto.
settings.py
Fichero de configuración del proyecto.
urls.py
Gestiona la tabla de urls a las que responde el proyecto.

Servidor web de desarrollo

El proyecto incorpora un servidor web:

$ cd sitio_encuestas
$ python manage.py runserver
Validating models...
 
0 errors found
Django version 1.3, using settings 'sitio_encuestas.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Comprobamos la dirección con el navegador o

$ curl -I  127.0.0.1:8000
HTTP/1.0 200 OK
Date: Mon, 22 Aug 2011 20:33:33 GMT
Server: WSGIServer/0.1 Python/2.7.1+
Content-Type: text/html
Icon present.gif
Tip: Podemos cambiar el puerto ejecutando:
 $ python manage.py runserver 8080

y También la ip:

 $ python manage.py runserver 0.0.0.0:8000


Este servidor ligero nos servirá para desarrollar el proyecto. No está pensado para sitios en producción. Para usar Django en producción, revisa la documentación: https://docs.djangoproject.com/en/1.3/howto/deployment/

Configuración del proyecto

Editar settings.py

Rutas absolutas

Como la configuración necesita rutas absolutas, podemos añadir esta función a settings.py:

import os
def ruta_abs(x):
    return os.path.join(os.path.abspath(os.path.dirname(__file__)), x)

Configuración de la base de datos

Por defecto, tiene sopote para Postgresql, MySQL, Sqlite y Oracle.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': '',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

Para usar sqlite:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': ruta_abs('encuestas.db'),                      # Or path to database file if using sqlite3.
    }
}
<source>
Para usar otra base de datos, tenemos que configurar el servidor con una base de datos y un usuario que tenga acceso a ella.
 
===configuración regional===
<source lang="python">
TIME_ZONE = 'Europe/Madrid'
LANGUAGE_CODE = 'es-es'

Aplicar los cambios

$python manage.py syncdb

Crea las tablas necesarias para el desarrollo de proyecto, incluyendo todas las aplicaciones incuidas en INSTALLED_APPS

Proyectos y aplicaciones

Para optimizar los recursos, un proyecto puede tener varias aplicaciones. Estas aplicaciones se pueden instalar en varios proyectos. Por eso se dice que las aplicaciones de django son "pluglables".

Creación de una aplicación

$ python manage.py startapp encuestas

Esto creará el siguiente directorio:

encuestas/
    __init__.py
    models.py
    views.py

Incluir la aplicación en el proyecto

Hay que añadir la nueva apliación a INSTALLED_APPS dentro de settings.py

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'sitio_encuestas.encuestas',
)

Definición de modelos

models.py

from django.db import models
 
class Encuesta(models.Model):
    pregunta = models.CharField(max_length=200)
    fecha_pub = models.DateTimeField(u'fecha de publicación')
 
    def __unicode__(self):
        return self.pregunta
 
class Opcion(models.Model):
    encuesta = models.ForeignKey(Encuesta)
    opcion = models.CharField(max_length=200)    
    votos = models.IntegerField()
 
    def __unicode__(self):
        return self.opcion

Ver sql

$ python manage.py sql encuestas

Esto hará que veamos el siguiente código SQL:

BEGIN;
CREATE TABLE "encuestas_encuesta" (
    "id" INTEGER NOT NULL PRIMARY KEY,
    "pregunta" VARCHAR(200) NOT NULL,
    "fecha_pub" datetime NOT NULL
)
;
CREATE TABLE "encuestas_opcion" (
    "id" INTEGER NOT NULL PRIMARY KEY,
    "encuesta_id" INTEGER NOT NULL REFERENCES "encuestas_encuesta" ("id"),
    "opcion" VARCHAR(200) NOT NULL,
    "votos" INTEGER NOT NULL
)
;
COMMIT;

Syncdb

Si el código es correcto, ejecutamos:

$ python manage.py syncdb
Creating table encuestas_encuesta
Creating table encuestas_opcion
 
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'lm'): lm
E-mail address: lm@micorreo.com
Password: 
Password (again): 
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
No fixtures found.

Si las tablas tienen datos, ya no modificará la estructura. Soluciones: eliminar los datos de esa aplicación o usar South: http://south.aeracode.org/

Acceso a los datos

$ python manage.py shell
>>> from encuestas.models import Encuesta, Pregunta # Importa las clases del modelo
 
# No hay encuestas
>>> Encuesta.objects.all()
[]
 
# Creamos una nueva encuesta
>>> import datetime
>>> p = Encuesta(pregunta="¿Cómo va el curso?", fecha_pub=datetime.datetime.now())
 
# Guardamos el objeto en la base de datos
>>> p.save()
 
# Creación de ID automática
>>> p.id
1
 
# Acceso a los valores
>>> p.pregunta
"¿Cómo va el curso?"
>>> p.fecha_pub
datetime.datetime(2011, 7, 15, 12, 00, 53)
 
# Cambio de valores de los atributos
>>> p.pub_date = datetime.datetime(2011, 7, 20, 0, 0)
>>> p.save()
 
# objects.all() muestra todas las encuestas de la base de datos
>>> Encuesta.objects.all()
[<Encuesta: ¿Cómo va el curso?]

Vemos el contenido de la encuesta porque hemos añadido el método __unicode__. Si no, veríamos <Encuesta: Encuesta object> Se crea el método __unicode__ y no __str__ porque los modelos de Django tratan con unicode por defecto.

# API de búsquedas de Django
>>> Encuesta.objects.filter(id=1)
[<Encuesta: ¿Cómo va el curso?>]
>>> Encuesta.objects.filter(pregunta__startswith='¿Cómo')
[<Encuesta: ¿Cómo va el curso?>]
 
# Obtener las encuestas de 2011
>>> Encuesta.objects.get(fecha_pub__year=2011)
<Encuesta: ¿Cómo va el curso?>
 
>>> Encuesta.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Encuesta matching query does not exist.
 
# Búsqueda por clave primaria
>>> Encuesta.objects.get(pk=1)
<Encuesta: ¿Cómo va el curso?>
 
# Vamos a insertar unas opciones para ver cómo funcionan las relaciones.
# Podemos crear las opciones desde la misma encuesta:
 
>>> p = Encuesta.objects.get(pk=1)
 
# Opciones relacionadas con nuestra encuesta:
>>> p.opcion_set.all()
[]
 
# Creamos tres opciones
>>> p.opcion_set.create(opcion='Muy bien', votos=0)
<Opcion: Muy bien>
>>> p.opcion_set.create(opcion='Bien', votos=0)
<Opcion: Bien>
>>> c = p.opcion_set.create(opcion='Regular', votos=0)
 
# Los objetos Opción tienen acceso desde la API a la encuesta a la que pertenecen:
>>> c.encuesta
<Encuesta: ¿Cómo va el curso?>
 
# Y viceversa. Los objetos Encuesta acceden a sus Opciones: 
>>> p.opcion_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> p.opcion_set.count()
3
 
# La API sigue de forma automática las relaciones.
# Para separar las relaciones se usan dobles guiones bajos.
# Busca todas las Opciones para cualquier encuesta publicada en 2011
>>> Opcion.objects.filter(encuesta__fecha_pub__year=2011)
[<Opcion: Muy bien>, <Opcion: Bien>, <Opcion: Regular>]
 
# Elimina una de las opciones: 
>>> c = p.opcion_set.filter(opcion__startswith='Regular')
>>> c.delete()

Otros métodos en los modelos

Podemos añadir métodos normales a los modelos:

import datetime
class Encuesta(models.Model):
    #...
    def publicada_hoy(self):
        return self.fecha_pub.date() == datetime.date.today()

Y podemos usarlos así:

>>> p = Escuesta.objects.get(pk=1)
>>> p.publicada_hoy()
False

Más información sobre las relaciones entre modelos: Acceder a objetos relacionados. Para más infor sobre cómo usar los dobles guiones bajos para hacer búsquedas por campos mediante la API: búsquedas mediante los campos Para más detalles sobre la API de la base de datos: Referencia de la Base de Datos.