xpanel, lxde, linux, fbpanel opensuse, linux, instalacion gtk3, gnome, ambienti grafici PS3, mandos, Play Station, Linux edubuntu, ubuntu, linux fedora, linux, discapacitados visuales fuduntu, fedora, ubuntu, linux, distribuciones inkscape, grafica, linux, editor tux, tuz, iconos, mascota, linux artistx, distro, linux, artistas, graficos

Guía de Django, el web framework para perfeccionistas (4a parte).

Modelos

Hemos visto los fundamentos de la construcción de sitios Web dinámicos con Django: la configuración de vistas y URLconfs. Como hemos explicado, una vista es responsable de hacer alguna lógica arbitraria, y luego devolver una respuesta. En uno de los ejemplos, nuestra lógica arbitraria fue calcular la fecha y hora actuales.

 

En las modernas aplicaciones Web, la lógica arbitraria implica a menudo interactúar con una base de datos. Un sitio web controlado por base de datos se conecta a un servidor de base de datos, recupera algunos de los datos, y muestra esos datos en una página Web. El sitio también puede proporcionar medios para que los visitantes rellenen la base de datos por su cuenta.

django logo

Django es muy adecuado para hacer sitios web controlados por base de datos porque viene con poderosas herramientas para la realización de consultas de base de datos usando Python. Este capítulo explica esta funcionalidad: la capa de base de datos de Django.

 

La forma “Tonta” de hacer consultas de base de datos en Vistas

Hay una manera “tonta” de recuperar datos de una base de datos en una vista. Es muy sencillo: sólo tiene que utilizar cualquier librería de Python existente para ejecutar una consulta SQL y hacer algo que con los resultados.

 

En esta vista de ejemplo, usamos la librería MySQLdb para conectarse a una base de datos MySQL, recuperar algunos registros, y pasarlos a una plantilla para mostrar como una página Web:

from django.shortcuts import render_to_response
import MySQLdb

def book_list(request):

db = MySQLdb.connect(user=’me’, db=’mydb’, passwd=’secret’, host=’localhost’)
cursor = db.cursor()
cursor.execute(‘SELECT name FROM books ORDER BY name’)
names = [row[0] for row in cursor.fetchall()]
db.close()
return render_to_response(‘book_list.html’, {‘names’: names})

Este enfoque funciona, pero algunos problemas saltan a la vista de inmediato:

  • Estamos codificando a pelo los parámetros de conexión a la base de datos. Idealmente, esos parámetros deberían almacenarse en la configuración de Django.
  • django
  • Estamos escribiendo una gran cantidad de código redundante: la creación de una conexión, la creación de un cursor, la ejecución de una sentencia, y el cierre de la conexión. Idealmente, todo lo que tendríamos que hacer es especificar que resultados queremos.
  • Esto está ligado a MySQL. Si, cambiamos de MySQL a PostgreSQL, vamos a tener que utilizar un adaptador de base de datos diferente, modificar los parámetros de la conexión, y dependiendo de la naturaleza de la instrucción SQL, posiblemente reescribir el código SQL. Idealmente, el servidor de base de datos que estamos utilizando debería abstraerse, de modo que un cambio de servidor de base de datos podría hacerse en un solo lugar. (Esta característica es especialmente útil si usted está construyendo una aplicación Django de fuente abierta que usted desea que sea usada por tanta gente como sea posible.)

Como es de esperar, la capa de base de datos de Django tiene por objeto resolver estos problemas. He aquí una vista previa de cómo la vista anterior se puede reescribir utilizando la API de base de datos de Django:

from django.shortcuts import render_to_response
from mysite.books.models import Book

def book_list(request):

books = Book.objects.order_by(‘name’)
return render_to_response(‘book_list.html’, {‘books’: books})

django_main

El patrón de desarrollo MTV (o MVC)

Antes de profundizar más en el código, vamos a considerar el diseño general de una aplicación web Django controlada por base de datos.

 

En las funciones de vista, por ejemplo, hablamos de la importancia de separar la lógica de negocio de la lógica de presentación mediante el uso de un sistema de plantillas. Con la capa de base de datos, aplicaremos la misma filosofía para la lógica de acceso a datos.

 

Estas tres piezas juntas – lógica de acceso a datos, lógica de negocio, y la lógica de presentación – constituyen un concepto que a menudo se denomina patrón de arquitectura de software Modelo-Vista-Controlador (MVC). En este patrón, “Modelo” hace referencia a la capa de acceso a datos, “Vista” hace referencia a la parte del sistema que selecciona qué mostrar y cómo mostrarlo, y “controlador” hace referencia a la parte del sistema que decide qué vista usar, en función de la entrada del usuario, accediendo al modelo cuando sea necesario.

 

Django sigue este patrón MVC lo suficientemente cerca que puede ser denominado un marco MVC. Así es más o menos cómo M, V, y C se descomponen en Django:

  • M, la parte de acceso a datos, está a cargo de la capa de base de datos de Django, que se describe en este capítulo.
  • V, la parte que selecciona los datos para mostrar y cómo mostrarlo, es manejado por las vistas y las plantillas.
  • C, la parte que delega a una vista en función de la entrada del usuario, es manejado por el marco en sí, siguiendo su URLconf y llamando a la función de Python adecuada para la dirección dada.

Debido a que la “C” es manejada por el propio marco y la mayor parte de la emoción en Django se produce en los modelos, plantillas, y vistas, Django ha sido denominado como un marco MTV. En el patrón de desarrollo MTV:

 

  • M significa “modelo”, la capa de acceso a datos. Esta capa todo lo relacionado con los datos: cómo acceder a ellos, cómo validarse, las relaciones entre los datos.
  • T representa “Plantilla”, la capa de presentación. Esta capa contiene las decisiones relacionadas con la presentación.
  • V significa “Vista”, la capa de lógica de negocio. Esta capa contiene la lógica que accede al modelo ylo remite a la plantilla adecuada(s). Usted puede verlo como el puente entre los modelos y plantillas.
  • django_slide_4
Configuración de la base de datos

En primer lugar, tenemos que realizar alguna configuración inicial, debemos decirle a Django qué servidor de base de datos utilizar y cómo conectarse a él.

 

Al igual que TEMPLATE_DIRS, la configuración de la base de datos reside en el archivo de configuración de Django, llamado settings.py por defecto. Editar el archivo y buscar la configuración de base de datos.

 

Una vez que haya introducido esa configuración y guarde settings.py, es bueno comprobar su configuración. Para ello, ejecute python manage.py shell, dentro del directorio del proyecto mysite.

>>> from django.db import connection
>>> cursor = connection.cursor()

Si no ocurre nada, entonces la base de datos está configurada correctamente. De lo contrario, comprobar el mensaje de error en busca de pistas acerca de lo que está fallando.

 

Su primera aplicación

Ahora que ha verificado que la conexión funciona, es hora de crear una aplicación Django, un paquete de código Django, que incluya modelos y vistas, que residan juntos en un paquete Python único y que representan una aplicación Django completa.

 

Ya creamos un proyecto en el capítulo 2, ¿cuál es la diferencia entre un proyecto y una aplicación?

 

  • Un proyecto es una instancia de un determinado conjunto de aplicaciones Django, más la configuración de esas aplicaciones.
  • Técnicamente, el único requisito de un proyecto es que suministra un archivo de configuración, que define la información de conexión de bases de datos, la lista de aplicaciones instaladas, el TEMPLATE_DIRS, y así sucesivamente.
  • Una aplicación es un conjunto portátil de funcionalidad Django, que generalmente incluye modelos y vistas, que residen juntos en un paquete único Python.
  • Por ejemplo, Django viene con una serie de aplicaciones, tales como un sistema de comentarios y una interfaz de administración automática. Un aspecto clave sobre estas aplicaciones es que son portables y reutilizables a través de múltiples proyectos.

Si usted está utilizando la capa de base de datos de Django (modelos), debe crear una aplicación Django. Los modelos deben residir dentro de aplicaciones. Así que, para empezar a escribir nuestros modelos, tendremos que crear una aplicación nueva.

 

En el directorio del proyecto mysite, escriba este comando para crear una aplicación books:

python manage.py startapp books

Este comando no produce ningún resultado, pero sí crea un directorio books en el directorio mysite.

books/

__init__.py
models.py
tests.py
views.py

Esto es el estado en blanco de su aplicación Django.

django_templates

Definir modelos en Python.

Un modelo de Django es una descripción de los datos en su base de datos, representada como código Python. Es su disposición de los datos – el equivalente de sus sentencias SQL CREATE TABLE, excepto que es en Python en lugar de SQL, y que incluye algo más que definiciones de columna de base de datos. Django usa un modelo para ejecutar código SQL y devolver estructuras de datos Python que representan las filas de las tablas de base de datos. Django también utiliza modelos para representar conceptos de alto nivel que SQL no necesariamente puede manejar. Si usted está familiarizado con bases de datos, su primer pensamiento podría ser: ¿No es redundante la definición de modelos de datos en Python en lugar de en SQL? Django funciona de manera que lo hace por varias razones:

 

  • A fin de proporcionar una API de acceso a datos conveniente, Django necesita saber el diseño de la bases de datos de alguna manera, y hay dos maneras de lograr esto. La primera es describir explícitamente los datos en Python, y la segunda es la introspección en la base de datos en tiempo de ejecución para determinar los modelos de datos.
  • Esta segunda vía parece más limpia, ya que los metadatos residen sólo en un lugar, pero introduce algunos problemas. En primer lugar, la introspección de una base de datos en tiempo de ejecución requiere sobrecarga. Si el marco ha de realizar la introspección cada vez que se procesa una solicitud, incurre en un nivel inaceptable de sobrecarga.  En segundo lugar, algunas bases de datos no guardan los suficientes metadatos para una introspección precisa y completa.
  • Escribir en Python es divertido, y mantener todo en Python limita el número de veces que su cerebro tiene que hacer un “cambio de contexto” lo que ayuda a la productividad.
  • Contar con modelos de datos almacenados como código en lugar de en su base de datos hace que sea más fácil de mantener sus modelos bajo control de versiones. De esta manera, usted puede fácilmente hacer un seguimiento de los cambios en sus diseños de datos.
  • SQL permite únicamente un grado determinado de metadatos acerca de un diseño de datos. La mayoría de los sistemas de base de datos, por ejemplo, no ofrecen un tipo de datos especializado para la representación de direcciones de e-mail o URL. Los modelos de Django lo hacen.
  • SQL es inconsistente a través de plataformas de base de datos. Si está distribuyendo una aplicación Web, por ejemplo, es mucho mejor distribuir un módulo Python que describa su diseño de datos que conjuntos distintos de sentencias CREATE TABLE para MySQL, PostgreSQL, y SQLite.
Su primer modelo

Nos centraremos en un diseño de datos basado en libro/autor/editor. Usaremos esto como ejemplo, porque las relaciones conceptuales entre libros, autores y editores son bien conocidas.

 

Vamos a suponer los siguientes conceptos, campos, y relaciones:

  • El autor tiene un nombre, un apellido y una dirección de correo electrónico.
  • Un editor tiene un nombre, una dirección, ciudad, estado o provincia, un país, y un sitio web.
  • Un libro tiene un título y una fecha de publicación. También tiene uno o más autores (relación de muchos a muchos con autores) y un solo editor (relación uno a muchos – clave ajena – con los editores).

El primer paso del uso de este diseño de base de datos con Django es expresarlo como código Python. En models.py, el archivo que fue creado por el comando startapp, escriba lo siguiente:

from django.db import models

class Publisher(models.Model):

name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()

class Author(models.Model):

first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()

class Book(models.Model):

title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()

django1

La primera cosa a notar es que cada modelo está representado por una clase Python que es una subclase de django.db.models.Model. La clase padre, Model, contiene toda la maquinaria necesaria para hacer que estos objetos sean capaces de interactuar con una base de datos. Lo crea o no, esto es todo el código que tiene que escribir para tener acceso básico a los datos con Django.

 

Cada modelo corresponde generalmente a una tabla de base de datos única, y cada atributo del modelo generalmente corresponde a una columna de esa tabla de base de datos. El nombre del atributo corresponde al nombre de la columna, y el tipo de campo (por ejemplo, CharField) corresponde al tipo de la columna de base de datos (por ejemplo, varchar).

 

Django puede generar el comando CREATE TABLE automáticamente, como mostraremos después.

 

La excepción a la regla de una clase por cada tabla de base de datos es el caso de las relaciones muchos-a-muchos. En nuestro modelo de ejemplo, el libro tiene un campo ManyToMany llamado autores. Esto designa que un libro tiene uno o varios autores, pero la tabla de base de datos Libros no tiene una columna de autores. En lugar de ello, Django crea una tabla adicional, una tabla de referencias cruzadas de muchos-a-muchos , que se encarga del mapeo de los libros a los autores.

 

Por último, tenga en cuenta que no hemos definido explícitamente una clave primaria en ninguno de estos modelos. A menos que usted lo indique, Django automáticamente le da a cada modelo una clave primaria de entero autonumérico llamado id. Cada modelo de Django necesita tener una clave primaria de una sola columna.

Instalar el modelo

 

Ahora vamos a crear las tablas en nuestra base de datos. Con el fin de hacer eso, el primer paso es activar estos modelos en nuestro proyecto Django. Lo hacemos mediante la adición de la aplicación books a la lista de “aplicaciones instaladas” en el archivo de configuración.

 

Edite el archivo settings.py de nuevo, y busque la propiedad INSTALLED_APPS, que le dice a Django que aplicaciones están activas para un proyecto determinado. De forma predeterminada, se ve algo como esto:

INSTALLED_APPS = (

‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.sites’,

)

Temporalmente comentemos las cuatro líneas poniendo una almohadilla (#) al principio de ellos. Comentenmos también la propiedad por defecto MIDDLEWARE_CLASSES.  A continuación, añadir: mysite.books a la lista INSTALLED_APPS, por lo que la propiedad finalmente podría parecerse a esto:

MIDDLEWARE_CLASSES = (

# ‘django.middleware.common.CommonMiddleware’,
# ‘django.contrib.sessions.middleware.SessionMiddleware’,
# ‘django.contrib.auth.middleware.AuthenticationMiddleware’,

)

INSTALLED_APPS = (

# ‘django.contrib.auth’,
# ‘django.contrib.contenttypes’,
# ‘django.contrib.sessions’,
# ‘django.contrib.sites’,
‘mysite.books’,

)

Ahora que la aplicación Django se ha activado en el archivo de configuración, podemos crear las tablas de base de datos en nuestra base de datos. En primer lugar, vamos a validar los modelos con la ejecución de este comando:

django3

python manage.py validate

Si sus modelos son válidos, ejecute el comando siguiente para que Django genere las declaraciones CREATE TABLE de los modelos de la aplicación books:

python manage.py sqlall books

El comando sqlall en realidad no crea las tablas en su base de datos – sólo imprime en pantalla la salida para que pueda ver el SQL que Django ejecutaría. Si quisiera, podría copiar y pegar este SQL en su cliente de base de datos. Sin embargo, Django proporciona una manera más fácil de llevar a cabo las sentencias SQL en la base de datos: el comando syncdb:

python manage.py syncdb

Ejecutando ese comando verá algo como esto:

Creating table books_publisher
Creating table books_author
Creating table books_book
Installing index for books.Book model

El comando syncdb es una simple “sincronización” de sus modelos a su base de datos. Busca en todos los modelos de cada aplicación en su propiedad INSTALLED_APPS, comprueba la base de datos para ver si las tablas apropiadas existen ya, y crea las tablas si no existen aún. Tenga en cuenta que syncdb no sincroniza los cambios en los modelos o las eliminaciones de los modelos; si usted hace un cambio a un modelo o elimina un modelo, y desea actualizar la base de datos, syncdb no gestionará eso.

 
Acceso básico a datos.

Una vez que ha creado un modelo, Django proporciona automáticamente una API de alto nivel Python para trabajar con esos modelos. Pruébelo mediante la ejecución de python manage.py shell y escribiendo lo siguiente:

>>> from books.models import Publisher
>>> p1 = Publisher(name=’Apress’, address=’2855 Telegraph Avenue’,
… city=’Berkeley’, state_province=’CA’, country=’U.S.A.’,
… website=’http://www.apress.com/’)
>>> p1.save()
>>> p2 = Publisher(name=”O’Reilly”, address=’10 Fawcett St.’,
… city=’Cambridge’, state_province=’MA’, country=’U.S.A.’,
… website=’http://www.oreilly.com/’)
>>> p2.save()
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>, <Publisher: Publisher object>]

Cuando crea objetos utilizando la API de modelos de Django, Django no guarda los objetos en la base de datos hasta que llama al método save():

p1 = Publisher(…)
# At this point, p1 is not saved to the database yet!
p1.save()
# Now it is.

Si desea crear un objeto y guardarlo en la base de datos en un solo paso, use el método objects.create(). Este ejemplo es equivalente al anterior:

>>> p1 = Publisher.objects.create(name=’Apress’,
… address=’2855 Telegraph Avenue’,
… city=’Berkeley’, state_province=’CA’, country=’U.S.A.’,
… website=’http://www.apress.com/’)
>>> p2 = Publisher.objects.create(name=”O’Reilly”,
… address=’10 Fawcett St.’, city=’Cambridge’,
… state_province=’MA’, country=’U.S.A.’,
… website=’http://www.oreilly.com/’)
>>> publisher_list = Publisher.objects.all()
>>> publisher_list

django4

Añadir representaciones de cadena del Modelo

Cuando mostramos la lista de editores, todo lo que obtuvimos en pantalla fue una vista inútil que hace difícil distinguir los objetos Publisher:

[<Publisher: Publisher object>, <Publisher: Publisher object>]

Podemos solucionar este problema fácilmente mediante la adición de un método llamado __unicode__() a nuestra clase Publisher. Un método __unicode__() le dice a Python cómo mostrar la representación “Unicode” de un objeto.

Puede ver esto en acción añadiendo un __unicode__() para los tres modelos:

from django.db import models

class Publisher(models.Model):

name = models.CharField(max_length=30)

address = models.CharField(max_length=50)

city = models.CharField(max_length=60)

state_province = models.CharField(max_length=30)

country = models.CharField(max_length=50)

website = models.URLField()

def __unicode__(self):

return self.name

class Author(models.Model):

first_name = models.CharField(max_length=30)

last_name = models.CharField(max_length=40)

email = models.EmailField()

def __unicode__(self):

return u’%s %s’ % (self.first_name, self.last_name)

class Book(models.Model):

title = models.CharField(max_length=100)

authors = models.ManyToManyField(Author)

publisher = models.ForeignKey(Publisher)

publication_date = models.DateField()

def __unicode__(self):

return self.title

Para que los cambios __unicode__() surtan efecto, salga de la shell de Python y entre de nuevo. (Esta es la forma más sencilla de hacer cambios en el código actual.) Ahora la lista de objetos Publisher es mucho más fácil de entender:

>>> from books.models import Publisher
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Apress>, <Publisher: O'Reilly>]

Notar que __unicode__() es un buen ejemplo de añadir comportamiento a los modelos. Un modelo Django describe más que el diseño de la tabla de base de datos de un objeto, sino también cualquier funcionalidad de un objeto que sepa hacer.  __unicode__() es un ejemplo de funcionalidad de este tipo; un modelo sabe cómo mostrarse a sí mismo.

 

Insertar y actualizar datos.

Para insertar una fila en la base de datos, primero debe crear una instancia de su modelo con argumentos de clave, así:

>>> p = Publisher(name=’Apress’,
… address=’2855 Telegraph Ave.’,
… city=’Berkeley’,
… state_province=’CA’,
… country=’U.S.A.’,
… website=’http://www.apress.com/’)

Este acto de crear instancias de un modelo de clase no afecta a la base de datos. El registro no se guarda en la base de datos hasta que llame a save():

>>> p.save()

Debido a que el modelo utiliza un ID de clave primaria autonumérica, la llamada inicial a save() hace una cosa más: calcula el valor de clave principal para el registro y lo coloca en el atributo id de la instancia:

>>> p.id
52 # this will differ based on your own data

Las llamadas posteriores a save() van a guardar el registro, sin crear un nuevo registro (es decir, realizar una instrucción SQL UPDATE en lugar de un INSERT).

>>> p.name = ‘Apress Publishing’
>>> p.save()

Tenga en cuenta que todos los campos serán actualizados, y no sólo los que han sido cambiados.

django-templates-0-317x450

Seleccionar objetos

Saber cómo crear y actualizar los registros de base de datos es esencial, pero es probable que las aplicaciones web que usted construya serán de hacer más consultas de los objetos existentes que de crear nuevos. Ya ha visto una manera de recuperar todos los registros para un determinado modelo:

>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]

Trasladado a SQL sería:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher;

Filtrar datos.

Naturalmente, es raro que desee seleccionar todo de una base de datos a la vez; en la mayoría de los casos, usted querrá tratar con un subconjunto de los datos. En la API de Django, puede filtrar los datos utilizando el método filter():

>>> Publisher.objects.filter(name=’Apress’)
[<Publisher: Apress>]

filter() toma los argumentos que se traducen en las cláusulas where de SQL apropiadas. El ejemplo anterior se traduciría en algo como:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name = ‘Apress’;

Se pueden pasar múltiples argumentos a filter() para reducir aún más las cosas:

>>> Publisher.objects.filter(country=”U.S.A.”, state_province=”CA”)
[<Publisher: Apress>]

Los múltiples argumentos se traducen en cláusulas AND de SQL. Así, el ejemplo se traduce en:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE country = ‘U.S.A.’
AND state_province = ‘CA’;

Tenga en cuenta que por defecto las búsquedas utilizan el operador = de SQL para hacer búsquedas de concordancia exacta. Otros tipos de búsqueda están disponibles:

>>> Publisher.objects.filter(name__contains=”press”)
[<Publisher: Apress>]

Hay un doble subrayado entre name y contains. Aquí, la parte __contains es traducida por Django en una sentencia LIKE de SQL:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name LIKE ‘%press%’;

Muchos otros tipos de búsquedas están disponibles, incluyendo icontains (LIKE insensible a mayúsculas/minúsculas), startswith y endswith, y range (consultas BETWEEN de SQL).

 

Recuperar objetos individuales.

El ejemplos de filter() anteriores devolvían un QuerySet, que se puede tratar como una lista. A veces es más conveniente extraer solamente un objeto individual en lugar de una lista. Para eso está el método get():

>>> Publisher.objects.get(name=”Apress”)
<Publisher: Apress>

Una consulta que devuelva varios objetos producirá una excepción:

>>> Publisher.objects.get(country=”U.S.A.”)
Traceback (most recent call last):

MultipleObjectsReturned: get() returned more than one Publisher –
it returned 2! Lookup parameters were {‘country’: ‘U.S.A.’}

Una consulta que no devuelva objetos también causará una excepción:

>>> Publisher.objects.get(name=”Penguin”)
Traceback (most recent call last):

DoesNotExist: Publisher matching query does not exist.

La excepción DoesNotExist es un atributo de la clase del modelo: Publisher.DoesNotExist. En sus aplicaciones, usted querrá atrapar estas excepciones, de esta forma:

try:

p = Publisher.objects.get(name=’Apress’)

except Publisher.DoesNotExist:

print “Apress isn’t in the database yet.”

else:

print “Apress is in the database.”

djangodesktop-1600x1200

Ordenar datos

En los ejemplos anteriores, usted puede descubrir que los objetos se devuelven en un orden aparentemente al azar. Estamos simplemente devolviendo los datos en un orden arbitrario elegido por la base de datos. En sus aplicaciones Django, usted probablemente querrá pedir sus resultados de acuerdo a un cierto criterio – por ejemplo, por orden alfabético. Para ello, utilizar el método order_by():

>>> Publisher.objects.order_by(“name”)
[<Publisher: Apress>, <Publisher: O'Reilly>]

Esto no parece muy diferente del all() del ejemplo anterior, pero el SQL ahora incluye un orden específico:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher
ORDER BY name;

Puede ordenar por el campo que quiera:

>>> Publisher.objects.order_by(“address”)
[<Publisher: O'Reilly>, <Publisher: Apress>]

>>> Publisher.objects.order_by(“state_province”)
[<Publisher: Apress>, <Publisher: O'Reilly>]

Para ordenar por múltiples campos usar varios argumentos:

>>> Publisher.objects.order_by(“state_province”, “address”)
[<Publisher: Apress>, <Publisher: O'Reilly>]

También puede especificar orden inverso anteponiendo al nombre del campo un – (esto es un signo menos):

>>> Publisher.objects.order_by(“-name”)
[<Publisher: O'Reilly>, <Publisher: Apress>]

Si bien esta flexibilidad es útil, utilizar order_by() todo el tiempo puede ser bastante repetitivo. La mayoría de las veces tendrá un campo particular por el querrá ordenar. En estos casos, Django permite especificar una ordenación predeterminada en el modelo:

class Publisher(models.Model):

name = models.CharField(max_length=30)

address = models.CharField(max_length=50)

city = models.CharField(max_length=60)

state_province = models.CharField(max_length=30)

country = models.CharField(max_length=50)

website = models.URLField()

def __unicode__(self):

return self.name

class Meta:

ordering = ['name']

En este caso, hemos introducido un nuevo concepto: la clase Meta, que es una clase que está incrustada dentro de la definición de la clase Publisher. Usted puede utilizar la clase Meta en cualquier modelo para especificar opciones específicas del modelo.

Si se especifica esto, le dice a Django que a menos que se indique un ordenamiento de forma explícita con order_by(), todos los objetos Publisher deben ser ordenados por el campo name cada vez que se recuperen con la API de Base de Datos de Django.

 

Encadenar búsquedas.

Hemos visto como filtrar datos y como ordenarlos. A menudo necesitaremos ambos. En estos casos, encadenar las búsquedas:

>>> Publisher.objects.filter(country=”U.S.A.”).order_by(“-name”)
[<Publisher: O'Reilly>, <Publisher: Apress>]

Esto se convierte a una sentencia SQL con WHERE y ORDER BY:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE country = ‘U.S.A’
ORDER BY name DESC;

Trocear datos.

Otra necesidad común es buscar sólo un número fijo de filas. Imagina que tiene miles de editores en su base de datos, pero que desea mostrar sólo el primero. Usted puede hacerlo con esta sintaxis:

>>> Publisher.objects.order_by(‘name’)[0]
<Publisher: Apress>

Esto se traduce en:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher
ORDER BY name
LIMIT 1;

De igual forma, usted puede recuperar un subconjunto específico de datos:

>>> Publisher.objects.order_by(‘name’)[0:2]

Esto devuelve 2 objetos, y se traduce en:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher
ORDER BY name
OFFSET 0 LIMIT 2;

Tener en cuenta que el índice negativo no está soportado:

>>> Publisher.objects.order_by(‘name’)[-1]
Traceback (most recent call last):

AssertionError: Negative indexing is not supported.

Esto es fácil de conseguir, sin embargo. Sólo cambiar la sentencia order_by() de esta forma:

>>> Publisher.objects.order_by(‘-name’)[0]

django-body1

Actualizar varios objetos en una sentencia.

Hemos señalado en la sección “Inserción y actualización de datos” que el método save() del modelo actualiza todas las columnas de una fila. Dependiendo de su aplicación, es posible que desee actualizar sólo un subconjunto de columnas.

Por ejemplo, supongamos que usted desea actualizar la editorial Apress para cambiar el nombre de ‘Apress’ a ‘Apress Publishing’. Usando save(), se vería algo como esto:

>>> p = Publisher.objects.get(name=’Apress’)
>>> p.name = ‘Apress Publishing’
>>> p.save()

Esto se traduce en el siguiente SQL:

SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name = ‘Apress’;

UPDATE books_publisher SET

name = ‘Apress Publishing’,

address = ’2855 Telegraph Ave.’,

city = ‘Berkeley’,

state_province = ‘CA’,

country = ‘U.S.A.’,

website = ‘http://www.apress.com’

WHERE id = 52;

El método save() de Django establece todos los valores de las columnas, no sólo la columna name. Si está en un entorno en el que otras columnas de la base de datos podrían cambiar a causa de algún otro proceso, es más inteligente cambiar sólo la columna que usted necesita. Para ello, utilice el método update() en objetos QuerySet. He aquí un ejemplo:

>>> Publisher.objects.filter(id=52).update(name=’Apress Publishing’)

La traducción a SQL es mucho más eficiente y no provoca efectos laterales:

UPDATE books_publisher
SET name = ‘Apress Publishing’
WHERE id = 52;

El método update() funciona en cualquier QuerySet, lo que significa que usted puede editar varios registros de forma masiva. He aquí cómo usted puede cambiar el país de ‘U.S.A.’ a ‘USA’ en todos los registros Publisher:

>>> Publisher.objects.all().update(country=’USA’)
2

El método update() devuelve un valor: un entero que representa cuántos registros han cambiado. En el ejemplo anterior, fue 2.

Eliminar objetos

Para eliminar un objeto de la base de datos, simplemente llamar al método delete():

>>> p = Publisher.objects.get(name=”O’Reilly”)
>>> p.delete()
>>> Publisher.objects.all()
[<Publisher: Apress Publishing>]

También puede eliminar objetos de forma masiva llamando al método delete() del resultado de cualquier QuerySet. Esto es similar al método update() que vimos en la última sección:

>>> Publisher.objects.filter(country=’USA’).delete()
>>> Publisher.objects.all().delete()
>>> Publisher.objects.all()
[]

Tenga cuidado al borrar sus datos. Como medida de precaución contra la supresión de todos los datos de una tabla particular, Django requiere que use explícitamente el método all() si desea borrar toda su tabla. Por ejemplo, esto no funciona:

>>> Publisher.objects.delete()
Traceback (most recent call last):
File ““, line 1, in
AttributeError: ‘Manager’ object has no attribute ‘delete’

Pero funciona si le añade el método all():

>>> Publisher.objects.all().delete()

Si está eliminando sólo un subconjunto de datos, no es necesario incluir all():

>>> Publisher.objects.filter(country=’USA’).delete()

mt_django

Si te ha gustado el artículo inscribete al feed clicando en la imagen más abajo para tenerte siempre actualizado sobre los nuevos contenidos del blog:

Espero que esta publicación te haya gustado. Si tienes alguna duda, consulta o quieras complementar este post, no dudes en escribir en la zona de comentarios. También puedes visitar Facebook, Twitter, Google +, Linkedin, Instagram, Pinterest y Feedly donde encontrarás información complementaria a este blog. COMPARTE EN!

0 comentarios:

Publicar un comentario

Archivo