O que o ORM oferece
Os modelos ganham por default um atributo «Modelo».objects que é um manager, através do qual você acessa toda a coleção de objetos do modelo (ou seja, operações no banco de dados a nível de tabela, e não registro).
A maioria dos métodos de managers na verdade são delegados para um QuerySet, e devolvem instâncias de QuerySet. Por exemplo, a chamada Livro.objects.all() devolve um QuerySet que engloba todos os registros da tabela de livros.
>>> from biblio.catalogo.models import *
>>> alice = Livro.objects.get(isbn='9780393048476')
>>> for c in alice.criador_set.all(): print c
...
Lewis Carroll
Martin Gardner
John Tenniel
>>> lc = alice.criador_set.get(nome__contains='Carroll')
>>> print lc.biografia.texto
Charles Lutwidge Dodgson, ou Lewis Carrol (Cheshire, 27 de janeiro de 1832 — Guildford, 14 de Janeiro de 1898) foi um escritor e matemático britânico. Lecionava matemática no Christ College, em Oxford).
>>>
Os mais usados são:
Força o ORM a realizar joins para buscar os objetos referentes e evitar acessos posteriores ao banco de dados.
Os «campos» são nomes de campos de referência (ForeignKey etc.). Pode-se usar a sintaxe referente__campo.
O único parâmetro nomeado aceito é depth, e serve para limitar a extensão dos relacionamentos a serem recuperados. *fields e depth não podem ser usados ao mesmo tempo.
Os critérios de busca usados em métodos de QuerySet são argumentos nomeados, com nomes formados por atributos do modelo e operadores como contains, in ou isnull, unidos por __ (dois underscores):
>>> lc = alice.criador_set.get(nome__icontains='Carroll') # operador __icontains
Alguns exemplos de critérios:
Corresponde ao SQL SELECT ... WHERE «campo» = «valor». Por conveniência, o operador __exact pode ser omitido, ou seja, a busca exata pode ser escrita assim:
>>> alice = Livro.objects.get(isbn='9780393048476') # busca exata
Operador menor que (less than). Corresponde ao SQL SELECT ... WHERE «campo» < '%«valor»%'. O operador lte é menor ou igual que (less than or equal). Há também os operadores gt e gte.
>>> livros_curtos = Livro.objects.filter(qt_paginas__lt=100) # <100 pgs.
O ORM do Django cria dinamicamente os seguintes atributos em cada instância i de um model:
O ORM do Django cria dinamicamente os seguintes métodos em cada instância i de um model:
Às vezes a ordem dos objetos em um «relacionado»_set é importante (por exemplo, os autores de um livro devem ser citados na ordem correta).
O parâmetro order_with_respect_to estabelece que os objetos relacionados devem manter sua ordem em relação aos seus referentes (ex. créditos em relação a livros).
class Credito(models.Model):
livro = models.ForeignKey(Livro)
criador = models.ForeignKey('Criador')
papel = models.CharField(max_length=64, blank=True)
class Meta:
order_with_respect_to = 'livro'
A ordem é mantida através de um campo _order (integer) criado automaticamente na tabela deste modelo.
O modelo referente (apontado pela ForeignKey) ganha os métodos dinâmicos get_«item»_order e set_«item»_order que permitem ler e alterar a ordem relativa dos itens relacionados.
>>> from biblio.catalogo.models import *
>>> livro = Livro.objects.get(isbn='9780393048476')
>>> livro
<Livro: The Annotated Alice>
>>> livro.get_credito_order()
[1, 2, 3]
>>> for c in livro.credito_set.all(): print c
The Annotated Alice: Lewis Carroll (autor)
The Annotated Alice: Martin Gardner (editor)
The Annotated Alice: John Tenniel (ilustrador)
>>> livro.set_credito_order([1,3,2])
>>> for c in alice.credito_set.all(): print c
The Annotated Alice: Lewis Carroll (autor)
The Annotated Alice: John Tenniel (ilustrador)
The Annotated Alice: Martin Gardner (editor)