Version 7 (modified by mario.caseiro at gmail.com, 18 years ago) ( diff )

--

THIS TRANSLATION IS IN PROGRESS:

This is an in progress translation document, that means there is somebody working on it. For more information on translating documents please look at TranslateDocumentation Wiki. Please do not edit this page.

Referência da API de Banco de Dados

Este documento cobre a versão 0.95 de Django e a versão do desenvolvimento. Docs anteriores: 0.90, 0.91

Uma vez que você criou seus data models, Django fornece automaticamente uma API de abstração de banco de dados para você criar, recuperar, atualizar e deletar objetos. Este documento descreve esta API .

Durante toda esta referência, iremos fazer referências aos modelos descritos abaixo, que compreenderiam uma aplicação de weblog.

class Blog(models.Model):
      name = models.CharField(maxlength=100)
      tagline = models.TextField()

      def __str__(self):
          return self.name

  class Author(models.Model):
      name = models.CharField(maxlength=50)
      email = models.URLField()

      def __str__(self):
          return self.name

  class Entry(models.Model):
      blog = models.ForeignKey(Blog)
      headline = models.CharField(maxlength=255)
      body_text = models.TextField()
      pub_date = models.DateTimeField()
      authors = models.ManyToManyField(Author)

      [imperfeita] def __str__(self):
          return self.name

Criando objetos

Para representar tabelas do banco de dados em objetos do Python, Django usa um sistema intuitivo: Uma classe modelo representa uma tabela da banco de dados, e uma instância dessa classe representa um registro particular na tabela do banco de dados

Para criar um objeto, instancie-o usando argumentos da classe modelo, então chame save() para salva-lo no banco de dados.

Você importa a classe modelo de onde quer que ela esteja dentro do Python path, como é de se esperar. (Nós destacamos isto aqui porque em versões anteriores do Django tinhamos importações de classes modelo conturbadas.)

Assumindo que os modelos estejam em um arquivo mysite/blog/models.py, segue o exemplo:

from mysite.blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()

Isto executa uma declaração SQL INSERT por baixo do panos. Django não conecta ao banco de dados até que você se chame explicitamente save().

O método save() não retorna valor algum.

Para criar um objeto e salvá-lo, tudo em um único passo veja o método create .

Auto incrementando chaves primárias

Se um modelo tiver um AutoField -- uma chave primária auto-increment -- então o valor auto incrementado será calculado e salvo como um atributo em seu objeto na primeira vez em que você chamar save().

Exemplo:

b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
b2.id     # Returns None, because b doesn't have an ID yet.
b2.save()
b2.id     # Returns the ID of your new object.

Não há maneira alguma de dizer qual será o valor de seu ID antes de chamar save(), pois o valor é obtido pelo do banco de dados, e não pelo Django.

(Para conveniência, por padrão cada modelo tem um AutoField nomeado id , a menos que você especifique explicitamente primary_key=True em um campo. Veja a documentação AutoField .)

Especificando explicitamente valores auto-primary-key

Caso tenha um modelo com um campo AutoField mas você queira definir o ID de um objeto explicitamente quando o salvar, é só defini-lo explicitamente antes de salvá-lo, ao invés de deixar a auto atribuição do ID.

Exemplo:

b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.')
b3.id     # Returns 3.
b3.save()
b3.id     # Returns 3.

Se você atribuir valores de chave-primária (auto-primary-keys) manualmente, certifique-se de não usar um valor já existente de chave primária! Se você criar um novo objeto com um valor explícito da chave-primária que já exista no banco de dados, Django irá supor que você está mudando o registro existente ao invés de criar um novo.

Dado o exemplo acima do blog 'Cheddar Talk' , este exemplo substituiria o registro antigo do banco de dados:

b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
b4.save()  # Overrides the previous blog with ID=3!

Veja Como Django decide entre UPDATE vs. INSERT , logo abaixo abaixo, para saber porque que isto acontece.

Especificar valores de chaves-primárias (auto-primary-keys) explicitamente é na maior parte útil para salvar grandes quantidades de objetos, uma vez que você está seguro que não terá conflitos de chaves-primárias

Salvando alterações nos Objetos

Para salvar alterações em um objeto que já exista no banco de dados, use save().

Dado a instância b5 do Blog, que já tenha sido salva no banco de dados, demonstramos no exemplo abaixo, como alterar seu nome e atualizar tal registro no banco de dados:

b5.name = 'New name'
b5.save()

Isto executa uma declaração SQL INSERT por detrás das cenas. Django não conecta ao banco de dados até que você chame explicitamente save().

O método save() não retorna valor algum.

Como Django decide entre UPDATE vs. INSERT

Você deve ter notado que os objetos de banco de dados do Django utiliza o mesmo método save() para criar e alterar objetos. Django abstrai a necessidade de utilizar declarações SQL de INSERT ou UPDATE. Especificamente, quando você chama save(), Django segue este algorítimo:

  • Caso o atributo chave-primária (primary-key) do objeto receba um valor que não resulte em False (assim como None ou strings vazias), Django executa uma query SELECT para determinar se já existe um registro com a chave-primária fornecida.
  • Caso já exista um registro com a chave-primária forncida, Django executa uma query de UPDATE.
  • Se o atributo do chave-primária (primary-key) do objeto não recebeu valor algum, ou recebeu um valor que não tenha registro, Django executa um INSERT.

A grande sacada aqui é que você deve ter cuidado para não especificar explicitamente um valor de chave-primária (primary-key) ao salvar novos objetos quando você não puder garantir que o valor da chave-primária (primary-key) não esteja sendo utilizado. Para mais sobre estes aspectos, ver "Especificando explicitamente valores auto-primary-key" , acima.

Recuperando objetos

Para recuperar objetos de seu banco de dados, você constrói um QuerySet através de um Manager (gerente) em sua classe de modelo.

Um QuerySet representa uma coleção dos objetos em seu banco de dados. Pode ter zero, um ou muitos filtros (filters) --critérios que reduzem, estreitam a coleção baseando-se em parâmetros fornecidos. Em termos SQL, um QuerySet equivale a uma declaração SELECT, e um filtro uma cláusula condicional como WHERE ou LIMIT.

Você obtém um QuerySet usando o Manager dos seus modelos (models class). Cada modelo tem pelo menos um Manager, e é chamado objects por padrão. Acesse-o diretamente através das classes modelos (models classes), dessa maneira:

Blog.objects  # <django.db.models.manager.Manager object at ...>
b = Blog(name='Foo', tagline='Bar')
b.objects     # AttributeError: "Manager isn't accessible via Blog instances."

(Managers são acessívei somente por via das classes modelos, e não pelas instâncias dos modelos, isto é para garantir a separação entre operações em níveis de tabelas ("table-level") das operações em níveis de registro ("record-level") )

O Manager é a principal fonte de QuerySets para um determinado modelo (model). Ele age como uma "raiz" das QuerySet que descrevem todos os objetos em tabelas de um determinado modelo no banco de dados. Por exemplo, Blog.objects é a QuerySet inicial que contém todos os objetos Blog no banco de dados.

Recuperando todos objetos

A maneira a mais simples de recuperar objetos de uma tabela é recuperá-los todos de uma vez.. Para fazer isto, use o método all() em um Manager.

Exemplo:

all_entries = Entry.objects.all()

O método all() retorna um QuerySet de todos os objetos no banco de dados.

(Já que Entry.objects é um QuerySet, porque nós não podemos utilizar Entry.objects? Isto ocorre porque Entry.objects, que é a QuerySet raíz , é um caso especial que não pode ser avaliado. O método all() retorna um QuerySet que pode ser avaliado.)

Filtrando objetos

A QuerySet raíz que é fornecida pelo Manager descreve todos os objetos de uma tabela no banco de dados. Embora usualmente, você venha utilizar somente parte (subset) deste completo conjunto de objetos.

Para criar tal parte do conjunto, você refina a QuerySet inicial, adicionando condições como filtros. As duas maneiras mais comuns para refinar um QuerySet são:

filter(**kwargs)
Retorna um novo QuerySet contendo objetos que casam com o determinado parâmetro de busca
exclude(**kwargs)
Retorna um novo QuerySet contendo objetos que não casam com o determinado parâmetro de busca

Os parâmetros de busca (**kwargs nas funções definidas acima) devem estar no format descrito abaixo em Field lookups.

Por exemplo, para obter um QuerySet das entradas de um blog desde o ano de 2006, use filter() dessa forma:

Entry.objects.filter(pub_date__year=2006)

(Note que não temos que adicionar um all() -- Entry.objects.all().filter(...). Isto também deve funcionar, porém você somente precisa usar all() quando você quiser todos os objetos da QuerySet raíz.)

Filtros encadeados

O resultado do refinamento de uma QuerySet é também um QuerySet, assim é possível encadear outros refinamentos. Por exemplo:

Entry.objects.filter(
    headline__startswith='What').exclude(
        pub_date__gte=datetime.now()).filter(
            pub_date__gte=datetime(2005, 1, 1))

...observe o QuerySet inicial com todas entradas contidas no banco de dados, inclua um filtro, depois uma exclusão, e depois outro filtro. O resultado final é um QuerySet contendo todas as entradas que o cabeçalho (headline) começe com "What", que foram publicados entre 1 de janeiro de 2005 e a data atual.

QuerySets filtrados são únicos

Cada vez que você refina um QuerySet, você recebe um novo QuerySet que de nenhuma maneira limita (influencía) o QuerySet anterior. Cada refinamento cría um QuerySet separado e distinto que pode ser armazenado, usado e reutilizado.

Exemplo:

q1 = Entry.objects.filter(headline__startswith="What")
q2 = q1.exclude(pub_date__gte=datetime.now())
q3 = q1.filter(pub_date__gte=datetime.now())

Estes três QuerySets estão separados. O primeiro é um QuerySet base contendo todas as entradas que possuem um cabeçalho (headline) que começa com ?What?. O segundo é um subconjunto do primeiro, com critérios adicionais que exclui os registros cujo pub_date são maiores do que a data atual. O terceiro é um subconjunto do primeiro, com critérios adicionais que selecionam somente os registros cujo pub_date são maiores que a data atual. O QuerySet inicial (q1) não é afetado pelo processo do refinamento.

QuerySets são preguiçosas

QuerySets são preguiçosas -- o ato de criar um QuerySet não envolve nenhuma atividade no banco de dados. Você pode utlizar filtros e mais filtros durante todo o dia e Django não rodará uma só query até que o QuerySet seja assimilado.

Quando QuerySets são avaliados

Você pode avaliar um QuerySet nas seguintes situações:

  • Iteration. O QuerySet é iterativo, e executa sua query no banco de dados na primeira vez que você itera sobre ele. Por exemplo, isto imprimirá o cabeçalho (headline) de todas as entradas no banco de dados:

    for e in Entry.objects.all():
        print e.headline
    
  • Slicing. Como explicado em Limitando QuerySets logo abaixo, um QuerySet pode ser dividido em parcelas, usando a sintaxe para extrair parcelas de array do Python. Geralmente cortar (extrair uma parcela) um QuerySet retorna outro (não avaliado / unevaluated) QuerySet, mas Django executará a query no banco de dados se você usar o parâmetro ?step? da sintaxe de extrair parcelas.

  • repr(). Um QuerySet está avaliado quando você chama repr() nele. Isto é para a conveniência do interpretador interativo do Python, assim você pode imediatamente ver seus resultados ao usar a API interativamente.

  • len(). Um QuerySet está avaliado quando você chamada len() nele. Isto, como é de se esperar, retorna o comprimento da lista resultante.

    Nota: Nào use len() em QuerySets se tudo que você quer fazer for determinar o número dos registros no conjunto. É muito mais eficiente manipular uma contagem no nível de banco de dados, usando SQL SELECT CONT(*), e Django fornece um método cont() precisamente por esta razão. Ver o cont() abaixo.

  • list(). Força ser avaliado um QuerySet chamando``list()`` nele. Por exemplo:

    entry_list = list(Entry.objects.all())
    

    Contudo esteja ciente, isto pode causar um grande overhead de memória, porque Django carregará cada elemento da lista na memória. Por sua vez, iterar sobre um``QuerySet`` tomará vantagem de seu banco de dados para carregar dados e instanciar objetos somente quando você os necessita.

Note: See TracWiki for help on using the wiki.
Back to Top