Referência das instâncias de Model

Esse documento descreve os detalhes da API Model. Isso foi feito baseado no material apresentado nos guias model e 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 models de exemplo do weblog apresentado no 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

Novo no Django 1.2: Please, see the release notes

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 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.

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.

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.

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.

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():

Model.save([force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS])
Novo no Django 1.0: The force_insert and force_update arguments were added.
Novo no Django 1.2: The using argument was added.

If you want customized saving behavior, you can override this save() method. See Sobrescrevendo métodos de model predefinidos 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

Novo no Django 1.0: Please, see the release notes
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 sinal 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 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.

Forçando um INSERT ou UPDATE

Novo no Django 1.0: Please, see the release notes

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 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 F() expressions and their use in update queries.

Deleting objects

Model.delete([using=DEFAULT_DB_ALIAS])
Novo no Django 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 Deletando objetos.

If you want customized deletion behavior, you can override this delete() method. See Sobrescrevendo métodos de model predefinidos for more details.

Outros métodos da instância de um model

Alguns métodos de objetos têm propostas especiais.

__str__

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__

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

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 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:

<a href="/people/{{ object.id }}/">{{ object.name }}</a>

Mas esse código é bem melhor:

<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>

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.

Métodos extra de instância

Além de save(), delete(), um objeto de modelo pode ter qualquer, ou todos os seguintes métodos:

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'
Model.get_next_by_FOO(**kwargs)
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 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.