.. .. META INFORMATION OF TRANSLATION .. .. $TranslationStatus: Done, waiting for revision $ .. $OriginalRevision: 15294 $ .. $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 :doc:`model ` e :doc:`consultas ao banco de dados `, 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 :doc:`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()``. .. _validating-objects: Validating objects ================== .. versionadded:: 1.2 There are three steps involved in validating a model: 1. Validate the model fields 2. Validate the model as a whole 3. Validate the field uniqueness All three steps are performed when you call by a model's ``full_clean()`` method. When you use a ``ModelForm``, the call to ``is_valid()`` will perform these validation steps for all the fields that are included on the form. (See the :doc:`ModelForm documentation ` for more information.) You should only need to call a model's ``full_clean()`` method if you plan to handle validation errors yourself, or if you have excluded fields from the ModelForm that require validation. .. method:: Model.full_clean(exclude=None) This method calls ``Model.clean_fields()``, ``Model.clean()``, and ``Model.validate_unique()``, in that order and raises a ``ValidationError`` that has a ``message_dict`` attribute containing errors from all three stages. The optional ``exclude`` argument can be used to provide a list of field names that can be excluded from validation and cleaning. ``ModelForm`` uses this argument to exclude fields that aren't present on your form from being validated since any errors raised could not be corrected by the user. Note that ``full_clean()`` will *not* be called automatically when you call your model's ``save()`` method, nor as a result of ``ModelForm`` validation. You'll need to call it manually when you want to run model validation outside of a ``ModelForm``. Example:: try: article.full_clean() except ValidationError, e: # Do something based on the errors contained in e.message_dict. # Display them to a user, or handle them programatically. The first step ``full_clean()`` performs is to clean each individual field. .. method:: Model.clean_fields(exclude=None) This method will validate all fields on your model. The optional ``exclude`` argument lets you provide a list of field names to exclude from validation. It will raise a ``ValidationError`` if any fields fail validation. The second step ``full_clean()`` performs is to call ``Model.clean()``. This method should be overridden to perform custom validation on your model. .. method:: Model.clean() This method should be used to provide custom model validation, and to modify attributes on your model if desired. For instance, you could use it to automatically provide a value for a field, or to do validation that requires access to more than a single field:: def clean(self): from django.core.exceptions import ValidationError # Don't allow draft entries to have a pub_date. if self.status == 'draft' and self.pub_date is not None: raise ValidationError('Draft entries may not have a publication date.') # Set the pub_date for published items if it hasn't been set already. if self.status == 'published' and self.pub_date is None: self.pub_date = datetime.datetime.now() Any ``ValidationError`` raised by ``Model.clean()`` will be stored under a special key that is used for errors that are tied to the entire model instead of to a specific field. You can access these errors with ``NON_FIELD_ERRORS``:: from django.core.exceptions import ValidationError, NON_FIELD_ERRORS try: article.full_clean() except ValidationError, e: non_field_errors = e.message_dict[NON_FIELD_ERRORS] Finally, ``full_clean()`` will check any unique constraints on your model. .. method:: Model.validate_unique(exclude=None) This method is similar to ``clean_fields``, but validates all uniqueness constraints on your model instead of individual field values. The optional ``exclude`` argument allows you to provide a list of field names to exclude from validation. It will raise a ``ValidationError`` if any fields fail validation. Note that if you provide an ``exclude`` argument to ``validate_unique``, any ``unique_together`` constraint that contains one of the fields you provided will not be checked. Salvando objetos ================ Para salvar um objeto no banco de dados, chame ``save()``: .. method:: Model.save([force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS]) .. versionadded:: 1.0 The ``force_insert`` and ``force_update`` arguments were added. .. versionadded:: 1.2 The ``using`` argument was added. If you want customized saving behavior, you can override this ``save()`` method. See :ref:`overriding-model-methods` for more details. The model save process also has some subtleties; see the sections below. 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 ou 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 :doc:`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 ou 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 circunstâncias, é 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. Updating attributes based on existing fields -------------------------------------------- Sometimes you'll need to perform a simple arithmetic task on a field, such as incrementing or decrementing the current value. The obvious way to achieve this is to do something like:: >>> product = Product.objects.get(name='Venezuelan Beaver Cheese') >>> product.number_sold += 1 >>> product.save() If the old ``number_sold`` value retrieved from the database was 10, then the value of 11 will be written back to the database. This can be optimized slightly by expressing the update relative to the original field value, rather than as an explicit assignment of a new value. Django provides :ref:`F() expressions ` as a way of performing this kind of relative update. Using ``F()`` expressions, the previous example would be expressed as:: >>> from django.db.models import F >>> product = Product.objects.get(name='Venezuelan Beaver Cheese') >>> product.number_sold = F('number_sold') + 1 >>> product.save() This approach doesn't use the initial value from the database. Instead, it makes the database do the update based on whatever value is current at the time that the save() is executed. Once the object has been saved, you must reload the object in order to access the actual value that was applied to the updated field:: >>> product = Products.objects.get(pk=product.pk) >>> print product.number_sold 42 For more details, see the documentation on :ref:`F() expressions ` and their :ref:`use in update queries `. Deleting objects ================ .. method:: Model.delete([using=DEFAULT_DB_ALIAS]) .. versionadded:: 1.2 The ``using`` argument was added. 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. For more details, including how to delete objects in bulk, see :ref:`topics-db-queries-delete`. If you want customized deletion behavior, you can override this ``delete()`` method. See :ref:`overriding-model-methods` for more details. .. _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 :doc:`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 :doc:`documentação do URL dispatch `. Métodos extra de instância ========================== 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 instância 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.