.. .. META INFORMATION OF TRANSLATION .. .. $TranslationStatus: Done, waiting for revision $ .. $OriginalRevision: 11348 $ .. $TranslationAuthors: Felipe.B.Zorzo, Robson Mendonça $ .. .. INFO OF THIS FILE (DO NOT EDIT! UPDATED BY SUBVERSION) .. .. $HeadURL$ .. $LastChangedRevision$ .. $LastChangedBy$ .. $LastChangedDate$ .. .. _ref-models-instances: ================================== Referência das instâncias de Model ================================== .. currentmodule:: django.db.models Esse documento descreve os detalhes da API ``Model``. Isso foi feito baseado no material apresentado nos guias :ref:`model ` e :ref:`consultas ao banco de datos `, então provavelmente você vai querer ler e entender esses documentos antes de ler este aqui. Durante essa referência, usaremos os :ref:`models de exemplo do weblog ` apresentado no :ref:`guia de consultas ao banco de dados `. Criando objetos =============== Para criar uma nova instância de um model, somente instancie-o assim como qualquer outra classe Python: .. class:: Model(**kwargs) Os argumentos são simplesmente os nomes dos campos que você definiu no seu model. Perceba que instanciando um model você não alterará o banco de dados; para isso, você precisa do ``save()``. Salvando objetos ================ Para salvar um objeto no banco de dados, chame ``save()``: .. method:: Model.save([force_insert=False, force_update=False]) É claro, há algumas legendas; veja as seções abaixo. .. versionadded:: 1.0 A assinatura do método ``save()`` tem mudou nas versões mais novas (``force_insert`` e ``force_update`` foram adicionados). Se você está sobrescrevendo estes métodos, esteja certo do uso correto da assinatura. Auto-incrementando chaves primárias ------------------------------------ Se um model possui um ``AutoField`` -- uma chave primária que auto-incrementa -- então o valor auto-increment será calculado e salvo como um atributo no seu objeto, na primeira vez que você chamar o método ``save()``:: >>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.') >>> b2.id # Retorna None, porque b nao tem um ID ainda. >>> b2.save() >>> b2.id # Retorna o ID de seu novo objeto. Não há meios de dizer qual será o valor do ID antes de você chamar o método ``save()``, porque este valor é calculado pelo banco de dados, não pelo Django. (Por conveniencia, cada modelo possui um ``AutoField`` chamado ``id``, por padrão, a menos que você explicitamente especifique ``primary_key=True`` em um campo. Veja a documentação para ``AutoField`` para saber mais detalhes. A propriedade ``pk`` ~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 1.0 .. attribute:: Model.pk Independentemente de saber se você vai definir uma chave primária, ou deixar o Django fazer isso por você, cada modelo irá ter uma propriedade chamada ``pk``. Ela se comporta como um atributo normal dentro do model, mas na verdade é um alias para qualquer atributo que seja a chave primária de seu model. Você pode acessar ou setar esse valor, como em qualquer outro atributo, e ele irá atualizar o campo correto do model. Especificando explicitamente valores para auto-primary-key ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Se um modelo tem um ``AutoField`` mas você quer definir um novo ID de objeto explicitamente quando salva, então defina-o explicitamente antes de salvar, em vez de confiar na auto-atribuição do ID:: >>> b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.') >>> b3.id # Retorna 3. >>> b3.save() >>> b3.id # Retorna 3. Se você atribui manualmente, valores para auto-primary-key, esteja certo de não usar um valor de primary-key já existente! Se você criar um novo objeto com um valor de chave primária explicito já existente no banco de dados, o Django irá assumir que você está alternado um dado existente ao invés de criar um novo. Como mostrado no exemplo acima, blog ``'Cheddar Talk'``, neste exemplo o dado será atualizado no banco de dados:: b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.') b4.save() # Sobrescreve o blog já existente com ID=3! Veja `Como o Django sabe quando fazer UPDATE vs. INSERT`_, abaixo, para entender por que isso acontece. Especificar explicitamente os valores de auto-primary-key é mais usual para salvar objetos em massa, quando você está certo de que não há colisões de chaves primárias. O que acontece quando você salva? --------------------------------- Quando você salva um objeto, o Django executa os seguintes passos: 1. **Emite um sinal pre-save.** O :ref:`sinal ` :attr:`django.db.models.signals.pre_save` é enviado, permitindo qualquer função ouvir o sinal para executar alguma ação personalizada. 2. **Pre-processa os dados.** Cada campo no objeto é consultado para realização de qualquer modificação dos dados que o campo possa precisar. A maioria dos campos não fazem pre-processamento -- o dado do campo é mantido como está. O pre-processamento é utilizado somente em campos que possuem um comportamento especial. Por exemplo, se seu modelo tem uma ``DateField`` com um ``auto_now=True``, o pre-save irá alterar o dado deste campo, assegurando que o campo comtém a data corrente. (Nossa documentação ainda não inclui a lista de todos os campos com este "comportamento especial.") 3. **Prepara os dados para o banco de dados.** Cada campo é consultado para prover seu valor corrente em um formato que pode ser escrito no banco de dados. Most fields require *no* data preparation. Simple data types, such as integers and strings, are 'ready to write' as a Python object. However, more complex data types often require some modification. Por exemplo, ``DataFields`` usam um objeto ``datetime`` do Python para armazenar o dado. O banco de dados não sabe armazenar objetos ``datetime``, então o valor do campo deve ser convertido em uma string compilada no formato de data ISO, para inserção no banco de dados. 4. **Insere o dado no banco de dados.** O dado pre-processado, preparado, é então composto em um chamada SQL para inserção no banco de dados. 5. **Emite um sinal post-save.** O sinal :attr:`django.db.models.post_save` é enviado, permitindo qualquer função ouvir o sinal para executar alguma ação personalizada. Como o Django sabe quando fazer UPDATE vs. INSERT ------------------------------------------------- Você pode ter notado que os objetos de banco de dados do Django, utilizam o mesmo método ``save()`` para criar e atualizar objetos. O Django abstrai a necessidade de uso do ``INSERT`` ou ``UPDATE``. Especificamente, quando você executa ``save()``, o Django segue este algorítmo: * Se o atributo chave primária do objeto está setado de forma a ser considerado ``verdadeiro`` (ex. um valor que não seja ``None`` ou uma string vazia), o Django executa um ``SELECT`` pra averiguar se existe algum dado com esta chave primária. * Se o dado com a chave primária não existe, o Django já existe, o Django executa uma consulta ``UPDATE``. * Se o atributo chave primária do objeto não está setado, ou se está, mas ela não existe no banco de dados, então o Django executa uma consulta ``INSERT``. O ponto aqui é que você deve ter cuidado para não especificar um valor de chave primária explicitamente ao salvar novos objetos, se você não tem como garantir que o valor não foi utilizado. Para mais sobre esta nuancia, veja `Especificando explicitamente valores para auto-primary-key`_ acima e `Forçando um INSERT ou UPDATE`_ abaixo. .. _ref-models-force-insert: Forçando um INSERT ou UPDATE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 1.0 Em algumas raras circumstancias, é necessário forçar o método ``save()`` a executar um SQL ``INSERT`` e não retroceder para fazer um ``UPDATE``. Ou vice-versa: atualizar, se possível, mas não inserir uma nova linha. Nestes casos você pode passar os parametros ``force_insert=True`` ou ``force_update=True`` para o método ``save()``. Utilizar ambos os parametros é um erro, tendo em vista que você não irá utilizar ambos, ``INSERT`` *e* ``UPDATE`` ao mesmo tempo. Deve ser muito raro você precisar usar estes parâmetros. O Django irá quase sempre fazer a coisa certa e tentar contornar isso irá conduzí-los a erros difíceis de rastrear. Esta funcionalidade é somente para usuários avandaçados. Deletando objetos ================= .. method:: Model.delete() Emite um SQL ``DELETE`` para um objeto. Este somente deleta o objeto no banco de dados; a instância do Python persistirá, e conterá dados em seus campos. .. _model-instance-methods: Outros métodos da instância de um model ======================================= Alguns métodos de objetos têm propostas especiais. ``__str__`` ----------- .. method:: Model.__str__() ``__str__()`` é um "método mágico" do Python que define o que deve ser retornado se você chamar ``str()`` sobre o objeto. O Django usa ``str(obj)`` (ou a função relacionada, ``unicode(obj)`` -- veja abaixo) em vários lugares, mais notavelmente como um valor mostrado para renderizar um objeto no site de administração do Django e como valores inseridos em um template quando é mostrado um objeto. Por isso, que você deve sempre retornar uma string, legível para humanos, dos métodos ``__str__``. Embora ele não seja obrigatório, é fortemente encorajado (veja a descrição de ``__unicode__``, abaixo, antes de por métodos ``__str__`` pra todo lado). Por examplo:: class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) def __str__(self): # Note o uso do django.utils.encoding.smart_str() aqui, por que # first_name e last_name serão strings unicode. return smart_str('%s %s' % (self.first_name, self.last_name)) ``__unicode__`` --------------- .. method:: Model.__unicode__() O método ``__unicode__()`` é chamado quando você executa ``unicode()`` sobre um objeto. Visto que os backends de banco de dados do Django retornarão strings Unicode para os atributos de seu model, você naturalmente irá querer escrever um método ``__unicode__()`` para seu model. O exemplo da seção anterior poderia ser escrito de maneira mais simples, como:: class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) def __unicode__(self): return u'%s %s' % (self.first_name, self.last_name) Se você define um método ``__unicode__()`` em seu modelo e não um método ``__str__()``, o Django irá automaticamente prover um método ``__str__()`` que chama o método ``__unicode__()`` e então converte o resultado corretamente para strings codificadas em UTF-8. Isto é uma prática de desenvolvimento recomendada: definir somente ``__unicode__()`` e deixar o Django se preocupar com a conversão das strings quando necessário. ``get_absolute_url`` -------------------- .. method:: Model.get_absolute_url() Definir um método ``get_absolute_url()`` pra dizer ao Django como calcular a URL para um objeto. Por exemplo:: def get_absolute_url(self): return "/people/%i/" % self.id O Django usa isto em sua interface de administração. Se um objeto define ``get_absolute_url()``, a página de edição do objeto terá um link "Veja no site" que aponta diretamente para a visão pública do objeto, de acordo com o ``get_absolute_url()``. Também, em outros lugares a mais, como no :ref:`framework de feeds `, o uso do ``get_absolute_url()`` como uma conveniencia para recompensar quem tenha definido o método. É uma boa prática usar o ``get_absolute_url()`` em templates, ao invés de escrever a mão as URLs de seus objetos. Por exemplo, este código de template não é legal:: {{ object.name }} Mas esse código é bem melhor:: {{ object.name }} .. note:: A string que você retorna do ``get_absolute_url()`` deve conter somente caracteres ASCII (exigidos pela especificação URI, `RFC 2396`_) que tenham sido codificados para URL, se necessário. Um template escrito usando ``get_absolute_url()`` deve ser capaz de utilizar o resultado diretamente sem a necessidade de qualquer outro tratamento. Você pode desejar usar a função ``django.utils.encoding.iri_to_uri()`` para ajudá-lo, se você estiver usando muitas strings unicode. .. _RFC 2396: http://www.ietf.org/rfc/rfc2396.txt O decorador ``permalink`` ~~~~~~~~~~~~~~~~~~~~~~~~~ O problema com a solução que descrevemos acima, utilizando o ``get_absolute_url()``, é que ela viola ligeiramente os principios DRY: a URL para este objeto é definida em ambos arquivo URLconf e no modelo. Você ainda pode dissociar seus modelos do URLconf utilizando o decorador ``permalink``: .. function:: permalink() Este decorador é passado para a função view, uma lista de parametros posicionais e (opcionalmente) um dicionário de parametros nomeados. o Django então constroi o caminho completo da URL, usando o URLConf, substituindo os parametros que você forneceu dentro da URL. Por exemplo, se seu URLConf contém uma linha como esta:: (r'^people/(\d+)/$', 'people.views.details'), ...seu model pode ter um método ``get_absolute_url`` que parece com isto:: from django.db import models @models.permalink def get_absolute_url(self): return ('people.views.details', [str(self.id)]) Similarmente, se você tem uma entrada no URLConf que pareça isto:: (r'/archive/(?P\d{4})/(?P\d{1,2})/(?P\d{1,2})/$', archive_view) ...você poderia referenciá-la usando o ``permalink()`` como a seguir:: @models.permalink def get_absolute_url(self): return ('archive_view', (), { 'year': self.created.year, 'month': self.created.month, 'day': self.created.day}) Observe que nós especificamos uma sequencia vazia para o segundo parametro neste caso, porque nós somente queremos passar parametros nomeados, ao invés de posicionais. Desta forma, você está amarrando a URL absoluta do model com a view que é usada para mostrá-lo, sem repetir as informações de URL. Você ainda pode usar o método ``get_absolute_url`` nos templates, como antes. Em alguns casos, como no caso de uso de generic views, ou no re-uso de views customizadas para múltiplos modelos, especificar a função de view pode confundir o reverse URL matcher (pois múltiplos padrões podem apontar para uma mesma view.) Para este problema, o Django utiliza **padrões de URL nomeados**. Usando padrões de URL nomeados, é possível ter um nome para um padrão, e então referenciar este nome ao invés da função view. Um padrão de URL nomeado é definida através da substituição da tupla padrão por uma chamada da função ``url``):: from django.conf.urls.defaults import * url(r'^people/(\d+)/$', 'django.views.generic.list_detail.object_detail', name='people_view'), ...e então usando este nome para fazer a reversão URL ao invés do nome da view:: from django.db.models import permalink def get_absolute_url(self): return ('people_view', [str(self.id)]) get_absolute_url = permalink(get_absolute_url) Mais detalhes sobre padrões de URL nomeadas estão em :ref:`documentação do URL dispatch `. Métodos extra de instancia ========================== Além de ``save()``, ``delete()``, um objeto de modelo pode ter qualquer, ou todos os seguintes métodos: .. method:: Model.get_FOO_display() Para todo campo que possui ``choices``, o objeto terá um método ``get_FOO_display()``, onde ``FOO`` é o nome do campo. Este método retorna o valor "legível para humanos" do campo. Por exemplo, no seguinte model:: GENDER_CHOICES = ( ('M', 'Male'), ('F', 'Female'), ) class Person(models.Model): name = models.CharField(max_length=20) gender = models.CharField(max_length=1, choices=GENDER_CHOICES) ...cada instancia de ``Person`` terá um método ``get_gender_display()``. Exemplo:: >>> p = Person(name='John', gender='M') >>> p.save() >>> p.gender 'M' >>> p.get_gender_display() 'Male' .. method:: Model.get_next_by_FOO(\**kwargs) .. method:: Model.get_previous_by_FOO(\**kwargs) Para todo ``DateField`` e ``DateTimeField`` que não possui ``null=True``, o objeto terá os métodos ``get_next_by_FOO()`` e ``get_previous_by_FOO()`` para o mesmo campo. Este retorna o próximo objeto ou o anterior correspondente ao campo de data, lançando a exceção apropriada ``DoesNotExist`` se for o caso. Ambos os métodos aceitam argumentos nomeados opicionalmente, que deve ser no formato descrito em :ref:`Field lookups `. Note que no caso de valores de datas idénticos, estes métodos irão usar o ID como solução de checagem. Isto garante que nenhum dado será pulado ou duplicado.