Unos pequeños apuntes cogidos al vuelo de consultas en django
Un queryset sería el equivalente a un SELECTUn filter sería el equivalente a un WHERE
Comandos de Query:
Objeto.objects.all() -> Todo el conjunto
Objeto.objects.filter() -> Un filtro para incluir
Objeto.objects.exclude() -> Un filtro para excluir
Objeto.objects.get() -> Busca un solo objeto
Encadenado de filtros
Entry.objects.filter(headline__startswith=’What’
).exclude(
pub_date__gte=datetime.now()
).filter(
pub_date__gte=datetime(2005,1,1)
)
Todos los que empiezan por What entre 1/1/2005 y ahora.
Cada filtro crea una consulta única
q1=Entry.objects.filter(headline__startswith=’What’)q2=q1.exclude(pub_date__gte=datetime.now())
q3=q2.filter(pub_date__gte=datetime(2005,1,1))
Buscar un solo objeto con get()
one_entry=Entry.objects.get(pk=1)Si no hay datos salta la excepción DoesNotExist
from django.core.exceptions import ObjectdoesNotExist
try:
one_entry=Entry.object.get(pk=numero)
except ObjectDoesNotExist, e:
mensaje=("La entrada %n no existe" % (numero))
En cambio filter()[0], no hace saltar ninguna excepción.
Limitar el número de registros devueltos
Entry.objects.all()[:5] # los cinco primerosEntry.objects.all()[5:10] # del quinto al décimo
Buscar sobre campos
Básicos: Son de la forma campo__tipobusqueda=valorEjemplo: Entry.objects.filter(pub_date___lte=’2006-01-01’) se transforma en select from blog_entry where pub_date<=’2006-01-01’
-> exact : headline__exact=’algo’
-> iexact: case insentive exact
-> contains
-> startswith
-> endswith
Relacionales
Entry.objects.filter(blog__name__exact=’Pep’)Blogs.objects.filter(entry__headline__contains=’Pep’, entry__pub_date__year=2006)
Todos los blogs que tengan alguna entrada cuyo titulo tenga Pep y se haya publicado en 2006
Blogs.objects.filter(entry__headline__contains=’Pep’).filter(entry__pub_date__year=2006)
Todos los que tengan Pep y todos los que se hayan publicado en 2006
Filtros que referencian a otros campos del mismo modelo
from django.db.models import FEntry.objects.filter(n_coments__gt=F(‘n_pingbacks’))
gt: greather than
n_pingbacks: valor de otro campo del mismo modelo
Primary key
Blog.objects.get(pk=valor).get(pk__in=[1,4,7])
.get(pk__gt=14)
Caching
Esta consulta se realiza dos veces:print [e.headline from p in queryset]
print [e.pub_date from p in queryset]
Esta, sólo una vez (cacheo de resultados):
queryset=Entry.objects.all()
print [p.headline form p in queryset] <- En esta se cachea
print [p.pub_date form p in queryset] <- en esta su usa la caché
Consultas complejas con Q
Las palabras clave en filter, etc... son ANDs, si queremos algo más complejo, necesitamos Qsdjango.db.models.Q
Q(question__startswith=’Who’) | Q(question__startswith=’What’)
Q(question__startswith=’Who’) | ~Q(question__startswith=’What’)
Poll.objects.get( Q(question__startswith=’Who’),
Q(pub_date=date(2005,5,2)) | Q(pub_date=date(2005,5,6)) )
Comparando objetos
Para comparar dos objetos usamos el == estándar de pythonuna_entrada==otra_entrada
La comparación se realiza siempre usando la clave primaria
Borrando objetos
Entry.objects.filter(pub_date__year=2005).delete()Borra todos los elementos y los foreign key que le apuntan en cascada
b=Blogs.objects.get(pk=1)
b.delete() -> borra la entrada y todos sus comentarios
Update de varios elementos
Entry.objects.filter().update(headline=’Cambiado’)Objetos relacionados
Si un modelo tiene un foreign key, podemos acceder al objeto foráneo via simple atributo del modelo:e=Blog.objects.get(id=1)
e.entry_set.all() --> todas las entradas del primer blog
e.entry_set.filter(headline__contains=’Pep’)
Si se ha usado el related_name en la definición del modelo, entonces ese es el nombre del atributo para acceder
blog=ForeignKey(Blog, related_name=’entries’)
b=Blog.objects.get(id=1)
b.entries.all()
b.entries.count()
Métodos del Foreign Manager:
relacionado.add(ob1, obj2, …) Añade al objeto relacionado
relacionado.create(**kwargs)
relacionado.remove(obj1, obj2, …)
relacionado.clear() -> borra todos los objetos relacionados
O también:
b=Blog.objects.get(id=1)
b.entry_set=[e1, e2, …] <- un objeto iterable
Hacer siempre el save del objeto principal para que permanente.