Code

Changes between Version 7 and Version 8 of DocPtDatabaseAPI


Ignore:
Timestamp:
10/12/06 12:22:35 (8 years ago)
Author:
mario.caseiro at gmail.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DocPtDatabaseAPI

    v7 v8  
    3737 
    3838Este documento cobre a versão 0.95 de Django e a versão do desenvolvimento. Docs anteriores: `0.90`_, `0.91`_ 
    39 ---------------------------------------------------------------------------------------------------------------- 
     39 
    4040 
    4141.. _0.90: http://www.djangoproject.com/documentation/0_90/  
     
    8989    from mysite.blog.models import Blog 
    9090    b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') 
     91 
    9192    b.save() 
    9293 
     
    119120 
    120121Especificando explicitamente valores  auto-primary-key  
    121 ------------------------------------------------------ 
     122~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     123 
    122124 
    123125Caso 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. 
     
    149151Para salvar alterações em um objeto que já exista no banco de dados, use ``save()``.  
    150152 
     153 
    151154Dado 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::  
    152155 
     
    177180Um ``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``.  
    178181 
     182 
    179183Você 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::  
    180184 
     
    214218    Retorna um novo ``QuerySet`` contendo objetos que casam com o determinado parâmetro de busca 
    215219 
     220 
    216221``exclude(**kwargs)`` 
    217222    Retorna um novo ``QuerySet`` contendo objetos que *não* casam com o determinado parâmetro de busca 
     
    228233 
    229234Filtros encadeados 
    230 ------------------ 
     235~~~~~~~~~~~~~~~~~~ 
    231236 
    232237O resultado do refinamento de uma ``QuerySet`` é também um ``QuerySet``, assim é possível encadear outros refinamentos. Por exemplo:: 
     
    252257Estes 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.  
    253258 
     259 
    254260QuerySets são preguiçosas 
    255261------------------------- 
     
    258264 
    259265 
    260 Quando QuerySets são avaliados 
    261 ------------------------------ 
     266Quando QuerySets são assímilados 
     267~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    262268 
    263269Você pode avaliar um ``QuerySet`` nas seguintes situações:  
    264270 
    265271    * **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::  
     272 
    266273 
    267274          for e in Entry.objects.all(): 
     
    285292------------------- 
    286293 
     294Use a syntax de extração de parcelas de arrays do  Python para limitar o seu ``QuerySet`` para um certo número de resultados. Isto é o equivalente das cláusulas SQL ``LIMIT`` e ``OFFSET``. 
     295 
     296Por exemplo, isto retorna os 5 primeiros objetos(``LIMIT 5``):: 
     297 
     298    Entry.objects.all()[:5] 
     299 
     300Isto retorna do quinto ao decimo objeto(``OFFSET 5 LIMIT 5``):: 
     301 
     302    Entry.objects.all()[5:10] 
     303 
     304Geralmente, extrair parcelas de um ``QuerySet`` retorna um ``QuerySet``  novo -- não avalía (executa) a query. Uma exceção é se você usar o parâmetro de ?step? da sintaxe da extração de parcelas do Python. Por exemplo, isto executaria realmente a query a fim de retornar uma lista de cada *segundo* objeto dos primeiros 10::  
     305 
     306    Entry.objects.all()[:10:2] 
     307 
     308 
     309Para recuperar um *único* objeto ao invés de uma lista  (por exemplo ``SELECT foo FROM bar LIMIT 1``), use simplismente um índice em vez de uma parcela (sclice). Por exemplo, isto retorna a primeira ``Entry`` no banco de dados, após ordenar entradas alfabeticamente pelo cabeçalho (headline)::  
     310 
     311    Entry.objects.order_by('headline')[0] 
     312 
     313Isto é aproximadamente equivalente a::  
     314 
     315    Entry.objects.order_by('headline')[0:1].get() 
     316 
     317Note, entretanto, que o primeiro destes levantará ``IndexError`` equanto o segundo levantará ``DoesNotExist`` se nenhum objeto combinar os critérios dados.  
     318 
     319Método de QuerySet que retornam novos QuerySets 
     320----------------------------------------------- 
     321 
     322Django fornece uma gama de métodos para refinamento de ``QuerySet`` que modificam ou os tipos de resultados retornados pelo ``QuerySet`` ou a maneira sua query SQL é executada.  
     323 
     324``filter(**kwargs)`` 
     325~~~~~~~~~~~~~~~~~~~~ 
     326 
     327Retorna um novo``QuerySet`` contendo objetos que casam com o determinado parâmetro de busca 
     328 
     329Os parâmetros de busca (``**kwargs``) devem estar no formato descrito em `Field lookups`_ logo abaixo. Múltiplos parametros são juntados via ``AND`` na declaração SQL subjacente. 
     330 
     331``exclude(**kwargs)`` 
     332~~~~~~~~~~~~~~~~~~~~~ 
     333 
     334Retorna um novo``QuerySet`` contendo objetos que *não* casam com o determinado parâmetro de busca 
     335 
     336Os parâmetros de busca (``**kwargs``) devem estar no formato descrito em `Field lookups`_ logo abaixo. Múltiplos parâmetros são juntados via ``AND`` na declaração SQL subjacente, e tudo isto  delimitado por ``NOT()``. 
     337 
     338 
     339 
     340 
     341Este exemplo exclue todas entradas que ``pub_date`` é a date/time corrente  E (AND) aqueles que o cabeçalho (``headline``) é  "Hello":: 
     342 
     343    Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello') 
     344 
     345em termos SQL, isto é assimilado como:: 
     346 
     347    SELECT ... 
     348    WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello') 
     349 
     350Este exemplo excluí todas entradas que ``pub_date`` é a date/time corrente OU (OR) aqueles que o cabeçalho (``headline``) é  "Hello":: 
     351 
     352    Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello') 
     353 
     354 
     355em termos SQL, isto é assimilado como:: 
     356 
     357    SELECT ... 
     358 
     359    WHERE NOT pub_date > '2005-1-3' AND NOT headline = 'Hello' 
     360 
     361Note que o segundo exemplo é mais restritivo. 
     362 
     363 
     364``order_by(*fields)`` 
     365~~~~~~~~~~~~~~~~~~~~~ 
     366 
     367Por padrão, os resultados retornados por um ``QuerySet`` são ordenados pela tupla dada na opção ``ordering`` no ``Meta`` do modelo. Você pode sobrescrever isto em  um ``QuerySet`` usando o método ``order_by``.  
     368 
     369Exemplo:: 
     370 
     371    Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline') 
     372 
     373O resultado acima será ordenado por ``pub_date`` decresente, então por ``headline`` crescente. O sinal negativo na frente de ``"-pub_date"`` indica a ordem *decrescente*. A ordem Crescente é implícita. Para requisitar aleatòria, use ``"?"``, como assim::  
     374 
     375    Entry.objects.order_by('?') 
     376 
     377Para ordenar por um campo de uma tabela diferente, adicione o nome da outra tabela e um ponto , assim como::  
     378 
     379    Entry.objects.order_by('blogs_blog.name', 'headline') 
     380 
     381Não há nenhuma maneira de especificar se a Ordenação deve ser "case sensitive". Com respeito à "case sensitive", Django ordenará os resultados apesar do backend de que seu banco de dados normalmente já os ordene .  
     382 
     383 
     384``distinct()`` 
     385~~~~~~~~~~~~~~ 
     386 
     387Retorna um novo ``QuerySet`` que utiliza ``SELECT DISTINCT`` na query SQL. Isto elimina linhas duplicadas dos resultados da query. 
     388 
     389Por padrão, um``QuerySet`` não irá eliminar linhas duplicadas. Na prática, isto  raramente é um problema, porque as querys simples tais como ``Blog.objects.all()`` não introduzem no resultado a possibilidade de linhas duplicadas.  
     390 
     391Entretanto, se sua query refere-se a múltiplas tabelas , é possível obter resultados duplicados quando um ``QuerySet`` é assimilado. Este é o caso de quando você deveria usar ``distinct()``.  
     392 
     393``values(*fields)`` 
     394~~~~~~~~~~~~~~~~~~~ 
     395 
     396Retorna um ``ValuesQuerySet`` -- um ``QuerySet`` que assimila uma lista de dicionários ao invés do modelo-instância de objetos.  
     397 
     398Cada um daqueles dicionários representa um objeto, com as chaves que correspondem aos nomes dos atributos dos objetos de modelo.  
     399 
     400Este exemplo compara os dicionários de ``values()`` com os objetos de modelo normais::  
     401 
     402    # Esta lista contem um objeto de Blog . 
     403    >>> Blog.objects.filter(name__startswith='Beatles') 
     404    [Beatles Blog] 
     405 
     406    # Esta lista contem um dicionário. 
     407    >>> Blog.objects.filter(name__startswith='Beatles').values() 
     408    [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}] 
     409 
     410``values()`` leva argumentos de posições opcionais, os ``*fields``, que especifica  nomes dos campos a que  ``SELETO`` deve se limitar. Se você especificar os campos, cada dicionário conterá somente as chaves/valores dos campos  que você especificou. Se você não especificar os campos, cada dicionário conterá uma chave e um valor para cada campo na tabela do banco de dados.  
     411 
     412Exemplo:: 
     413 
     414    >>> Blog.objects.values() 
     415    [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}], 
     416    >>> Blog.objects.values('id', 'name') 
     417    [{'id': 1, 'name': 'Beatles Blog'}] 
     418 
     419Um ``ValuesQuerySet`` é útil quando você sabe que você necessitará somente valores de um pequeno número de campos disponíveis e você não necessitará  a funcionalidade da instância de um objeto de modelo. É mais eficiente selecionar somente os campos que você necessita usar.  
     420 
     421Finalmente, note que um ``ValuesQuerySet`` é uma subclasse de ``QuerySet``, assim possui todos os métodos de ``QuerySet``. Você pode chamar ``filter()`` nele, ou ``order_by()``, ou outro método qualquer. Sim, isso significa que estas duas chamadas são idênticas::  
     422 
     423    Blog.objects.values().order_by('id') 
     424    Blog.objects.order_by('id').values() 
     425 
     426As pessoas que fizeram Django preferem pôr todos os métodos SQL de alterações primeiro, seguido (opcionalmente) por quaisquer métodos de manipulem saída (tais como ``values()``), mas isso não importa realmente. Esta é sua oportunidade de realmente "flaunt" seu individualismo.  
     427 
     428``dates(field, kind, order='ASC')`` 
     429~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     430 
     431Retorna um ``DateQuerySet`` -- um ``QuerySet`` que assimila uma lista de  ``datetime.datetime`` objetos representando todas as datas disponíveis de um tipo particular dentro dos conteúdos do ``QuerySet``.  
     432 
     433``field`` deve ser o nome de um ``DateField`` ou ``DateTimeField`` de seu modelo 
     434 
     435``tipo`` (kind) deve ser tanto ``"year"``, ``"month"`` ou ``"day"``. Cada ``datetime.datetime`` objeto na lista resultante é truncado ("truncated") ao tipo (``type``) fornecido. 
     436 
     437    * ``"year"`` retorna uma lista de todos os valores distintos de ANOS para o campo. 
     438    * ``"month"`` retorna uma lista de todos os valores distintos de MESES para o campo. 
     439    * ``"day"`` retorna uma lista de todos os valores distintos de DIAS para o campo. 
     440 
     441``order``, que por padrão é ``'ASC'``, deve ser tanto ``'ASC'`` (crescente) ou ``'DESC'`` (decrescente). Isto especifica a ordem dos resultados. 
     442 
     443Exemplos:: 
     444 
     445    >>> Entry.objects.dates('pub_date', 'year') 
     446    [datetime.datetime(2005, 1, 1)] 
     447    >>> Entry.objects.dates('pub_date', 'month') 
     448    [datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)] 
     449    >>> Entry.objects.dates('pub_date', 'day') 
     450    [datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)] 
     451    >>> Entry.objects.dates('pub_date', 'day', order='DESC') 
     452    [datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)] 
     453    >>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day') 
     454    [datetime.datetime(2005, 3, 20)] 
     455 
     456``select_related()`` 
     457~~~~~~~~~~~~~~~~~~~~ 
     458Retorna um ``QuerySet`` que automaticamente "segue"  os relacionamentos de chave-estrangeira, selecionando os dados adicionais do objeto-relacionado quando executa a query. Este é um impulsionador de desempenho que resulta  em querys (às vezes, muito)maiores mas o uso posterior dos relacionamentos de chave-estrangeiras não requerem novas queries no banco de dados.  
     459 
     460Os seguintes exemplos ilustram a diferença entre buscas simples e buscas ``select_related()``. Está aqui a busca padrão::  
     461 
     462    # Aciona o banco de dados. 
     463    e = Entry.objects.get(id=5) 
     464 
     465    # Aciona o banco de dados novamente para obter o objeto Blog relacionado. 
     466    b = e.blog 
     467 
     468Agora a busca ``select_related`` :: 
     469 
     470    # Aciona o banco de dados. 
     471    e = Entry.objects.select_related().get(id=5) 
     472 
     473    # Não aciona o banco de dados, porque e.blog já foi previamente populado na query anterior. 
     474    b = e.blog 
     475 
     476``select_related()`` segue as chaves-estrangeiras tão longe quanto possível. Se você tiver os seguintes modelos: 
     477 
     478    class City(models.Model): 
     479        # ... 
     480 
     481    class Person(models.Model): 
     482        # ... 
     483        hometown = models.ForeignKey(City) 
     484 
     485    class Book(models.Model): 
     486        # ... 
     487        author = models.ForeignKey(Person) 
     488 
     489...então chamar ``Book.objects.select_related().get(id=4)`` irá fazer um cache da pessoa (``Person``) relacionada *e* da cidade (``City``) relacionada:: 
     490 
     491    b = Book.objects.select_related().get(id=4) 
     492    p = b.author         # Não aciona o banco de dados. 
     493    c = p.hometown       # Não aciona o banco de dados.. 
     494 
     495    sv = Book.objects.get(id=4) # Sem select_related() neste exemplo. 
     496    p = b.author         # Aciona o banco de dados. 
     497    c = p.hometown       # Aciona o banco de dados. 
     498 
     499Note que ``select_related()`` não segue chaves-estrangeiras que tenham ``null=True``. 
     500 
     501``extra(select=None, where=None, params=None, tables=None)`` 
     502~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     503Às vezes, a sintaxe de query do Django por sí não pode fàcilmente expressar uma cláusula ``WHERE`` complexa. Para estes casos limitados, Django fornece o modificador de ``QuerySet`` ``extra()``-- uma brecha para injetar cláusulas específicas no SQL gerado pelo ``QuerySet``.  
     504 
     505Por definição, estas buscas extras podem não ser portáveis aos diferentes engines de banco de dados (porque você está escrevendo explicitamente um código SQL) e viola o princípio DRY, assim você deve evitá-los sempre que possível.  
     506 
     507 
     508 
    287509}}} 
    288510