Changes between Version 7 and Version 8 of DocPtDatabaseAPI


Ignore:
Timestamp:
10/12/06 14: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
Back to Top