You are on page 1of 18

Django

Documentação

Modelos
Um modelo é a fonte única e de nitiva de informações sobre seus dados. Ele contém os campos e comportamentos essenciais dos dados que você está armazenando. Geralmente,
cada modelo mapeia para uma única tabela de banco de dados.

O básico:

Cada modelo é uma classe Python que é subclasse django.db.models.Model.

Cada atributo do modelo representa um campo de banco de dados.

Com tudo isso, o Django oferece uma API de acesso ao banco de dados gerada automaticamente; consulte Fazendo consultas .

Exemplo rápido
Este modelo de exemplo de ne a Person, que tem um first_namee last_name:

from django.db import models

class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)

first_namee last_namesão campos do modelo. Cada campo é especi cado como um atributo de classe e cada atributo é mapeado para uma coluna do banco de dados.

O Personmodelo acima criaria uma tabela de banco de dados como esta:

CREATE TABLE myapp_person (


"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);

Algumas notas técnicas:

O nome da tabela myapp_personé derivado automaticamente de alguns metadados do modelo, mas pode ser substituído. Veja os nomes das tabelas para mais detalhes.

Um idcampo é adicionado automaticamente, mas esse comportamento pode ser substituído. Veja Campos de chave primária automáticos .

O SQL neste exemplo é formatado usando a sintaxe do PostgreSQL, mas vale a pena observar que o Django usa o SQL customizado para o backend de banco de dados
especi cado em seu arquivo de con gurações .CREATE TABLE

Usando modelos
Uma vez que você tenha de nido seus modelos, você precisa dizer ao Django que você vai usar esses modelos. Faça isso editando o arquivo de con gurações e alterando a
INSTALLED_APPScon guração para adicionar o nome do módulo que contém o seu models.py.

Por exemplo, se os modelos para seu aplicativo residirem no módulo myapp.models(a estrutura de pacote criada para um aplicativo pelo script), deverá ler, em parte:manage.py
startappINSTALLED_APPS

INSTALLED_APPS = [
#...
'myapp',
#... Idioma: en
]

Versão da documentação: 2.1


Ao adicionar novos aplicativos INSTALLED_APPS, execute-os , opcionalmente, fazendo migrações para eles primeiro .manage.py migratemanage.py makemigrations

Campos
A parte mais importante de um modelo - e a única parte necessária de um modelo - é a lista de campos de banco de dados de nidos. Campos são especi cados por atributos de classe.
Tenha cuidado para não escolher nomes de campo que con ito com a modelos API como clean, saveou delete.

Exemplo:

from django.db import models

class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)

class Album(models.Model):
artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()

Tipos de campo
Cada campo no seu modelo deve ser uma instância da Fieldclasse apropriada . O Django usa os tipos de classes de campo para determinar algumas coisas:

O tipo de coluna, que conta a base de dados que tipo de dados para armazenar (por exemplo INTEGER, VARCHAR, TEXT).

O widget HTML padrão a ser usado ao renderizar um campo de formulário (por exemplo , ).<input type="text"><select>

Os requisitos mínimos de validação, usados no admin do Django e em formulários gerados automaticamente.

O Django é enviado com dezenas de tipos de campos internos; você pode encontrar a lista completa na referência de campo do modelo . Você pode facilmente escrever seus próprios
campos se os elementos internos do Django não funcionarem. consulte Escrevendo campos de modelo customizado .

Opções de campo
Cada campo recebe um certo conjunto de argumentos especí cos de campo (documentados na referência de campo do modelo ). Por exemplo, CharField(e suas subclasses) exigem
um max_lengthargumento que especi que o tamanho do VARCHARcampo do banco de dados usado para armazenar os dados.

Há também um conjunto de argumentos comuns disponíveis para todos os tipos de campo. Todos são opcionais. Eles estão totalmente explicados na referência , mas aqui está um
breve resumo dos mais usados:

null
Se True, o Django irá armazenar valores vazios como NULLno banco de dados. O padrão é False.

blank

Se True, o campo tiver permissão para car em branco. O padrão é False.

Note que isto é diferente de null. nullé puramente relacionado ao banco de dados, enquanto blankestá relacionado à validação. Se um campo tiver blank=True, a validação de
formulário permitirá a entrada de um valor vazio. Se um campo tiver blank=False, o campo será obrigatório.

choices

Uma iterável (por exemplo, uma lista ou tupla) de duas tuplas para usar como opções para este campo. Se isso for fornecido, o widget de formulário padrão será uma caixa de seleção
em vez do campo de texto padrão e limitará as escolhas às opções fornecidas.

Uma lista de opções é assim:

YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
('GR', 'Graduate'),
) Idioma: en

Versão da documentação: 2.1

O primeiro elemento em cada tupla é o valor que será armazenado no banco de dados. O segundo elemento é exibido pelo widget de formulário do campo.
Dada uma instância do modelo, o valor de exibição de um campo com choicespode ser acessado usando o get_FOO_display() método. Por exemplo:

from django.db import models

class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)

>>> p = Person(name="Fred Flintstone", shirt_size="L")


>>> p.save()
>>> p.shirt_size
'L'
>>> p.get_shirt_size_display()
'Large'

default
O valor padrão para o campo. Isso pode ser um valor ou um objeto que pode ser chamado. Se callable, será chamado toda vez que um novo objeto for criado.

help_text
Texto extra de “ajuda” a ser exibido com o widget de formulário. É útil para documentação, mesmo que seu campo não seja usado em um formulário.

primary_key

Se True, este campo é a chave primária do modelo.

Se você não especi car primary_key=Truenenhum campo em seu modelo, o Django adicionará automaticamente um IntegerFieldpara manter a chave primária, assim você não
precisa de nir primary_key=Trueem nenhum dos seus campos, a menos que você queira sobrescrever o comportamento padrão da chave primária. Para mais, consulte Campos de
chave primária automáticos .

O campo da chave primária é somente leitura. Se você alterar o valor da chave primária em um objeto existente e depois salvá-lo, um novo objeto será criado ao lado do antigo. Por
exemplo:

from django.db import models

class Fruit(models.Model):
name = models.CharField(max_length=100, primary_key=True)

>>> fruit = Fruit.objects.create(name='Apple')


>>> fruit.name = 'Pear'
>>> fruit.save()
>>> Fruit.objects.values_list('name', flat=True)
<QuerySet ['Apple', 'Pear']>

unique
Se True, este campo deve ser único em toda a tabela.

Mais uma vez, estas são apenas breves descrições das opções de campo mais comuns. Detalhes completos podem ser encontrados na referência de opção de campo de modelo
comum .

Campos de chave primária automáticos


Por padrão, o Django dá a cada modelo o seguinte campo:

Idioma: en
id = models.AutoField(primary_key=True)

Versão da documentação: 2.1


Essa é uma chave primária de incremento automático.

Se você quiser especi car uma chave primária personalizada, basta especi car primary_key=Trueem um dos seus campos. Se o Django ver que você de niu explicitamente
Field.primary_key, ele não adicionará a idcoluna automática .

Cada modelo requer exatamente um campo para ter primary_key=True(explicitamente declarado ou adicionado automaticamente).

Nomes de campos detalhados


Cada tipo de campo, exceto para ForeignKey, ManyToManyFielde OneToOneField, leva um primeiro argumento opcional - um nome por extenso. Se o nome detalhado não for dado,
o Django irá criá-lo automaticamente usando o nome do atributo do campo, convertendo sublinhados em espaços.

Neste exemplo, o nome detalhado é :"person's first name"

first_name = models.CharField("person's first name", max_length=30)

Neste exemplo, o nome detalhado é :"first name"

first_name = models.CharField(max_length=30)

ForeignKey, ManyToManyFielde OneToOneFieldrequer que o primeiro argumento seja uma classe de modelo, então use o verbose_nameargumento keyword:

poll = models.ForeignKey(
Poll,
on_delete=models.CASCADE,
verbose_name="the related poll",
)
sites = models.ManyToManyField(Site, verbose_name="list of sites")
place = models.OneToOneField(
Place,
on_delete=models.CASCADE,
verbose_name="related place",
)

A convenção não é capitalizar a primeira letra do verbose_name. O Django irá automaticamente capitalizar a primeira letra onde for necessário.

Relacionamentos
Claramente, o poder dos bancos de dados relacionais está em relacionar as tabelas entre si. O Django oferece maneiras de de nir os três tipos mais comuns de relacionamentos com
bancos de dados: muitos para um, muitos para muitos e um para um.

Relacionamentos muitos para um

Para de nir um relacionamento muitos para um, use django.db.models.ForeignKey. Você o usa como qualquer outro Fieldtipo: incluindo-o como um atributo de classe do seu
modelo.

ForeignKey requer um argumento posicional: a classe à qual o modelo está relacionado.

Por exemplo, se um Carmodelo tem um Manufacturer- isto é, um Manufacturerfaz vários carros, mas cada Carum tem apenas um Manufacturer- use as seguintes de nições:

from django.db import models

class Manufacturer(models.Model):
# ...
pass

class Car(models.Model):
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE) Idioma: en
# ...

Versão da documentação: 2.1


Você também pode criar relacionamentos recursivos (um objeto com um relacionamento muitos para um) e relacionamentos com modelos ainda não de nidos ; consulte a referência de
campo do modelo para obter detalhes.

É sugerido, mas não obrigatório, que o nome de um ForeignKeycampo ( manufacturerno exemplo acima) seja o nome do modelo, em minúsculas. Você pode, claro, ligar para o
campo como quiser. Por exemplo:

class Car(models.Model):
company_that_makes_it = models.ForeignKey(
Manufacturer,
on_delete=models.CASCADE,
)
# ...

Veja também

 ForeignKeycampos aceitam um número de argumentos extras que são explicados na referência de campo do modelo . Essas opções ajudam a de nir como o
relacionamento deve funcionar; todos são opcionais.

Para obter detalhes sobre o acesso a objetos relacionados a retrocessos, consulte o exemplo a seguir de relacionamentos a seguir .

Para código de amostra, consulte o exemplo do modelo de relacionamento Muitos para um .

Relacionamentos muitos para muitos

Para de nir um relacionamento muitos para muitos, use ManyToManyField. Você o usa como qualquer outro Fieldtipo: incluindo-o como um atributo de classe do seu modelo.

ManyToManyField requer um argumento posicional: a classe à qual o modelo está relacionado.

Por exemplo, se a Pizzatem vários Toppingobjetos - ou seja, um Toppingpode estar em várias pizzas e cada um Pizzatem várias coberturas - veja como você pode representar isso:

from django.db import models

class Topping(models.Model):
# ...
pass

class Pizza(models.Model):
# ...
toppings = models.ManyToManyField(Topping)

Assim como ForeignKey, você também pode criar relacionamentos recursivos (um objeto com um relacionamento muitos-para-muitos para si mesmo) e relacionamentos com
modelos ainda não de nidos .

É sugerido, mas não obrigatório, que o nome de um ManyToManyField( toppingsno exemplo acima) seja um plural descrevendo o conjunto de objetos de modelo relacionados.

Não importa qual modelo tenha o ManyToManyField, mas você só deve colocá-lo em um dos modelos - não em ambos.

Geralmente, ManyToManyFieldinstâncias devem ir no objeto que será editado em um formulário. No exemplo acima, toppingsestá em Pizza(ao invés de Toppingter um pizzas
ManyToManyField) porque é mais natural pensar em uma pizza com coberturas do que em um topping estar em várias pizzas. A maneira como é con gurada acima, o
Pizzaformulário permitiria que os usuários selecionassem as coberturas.

Veja também

 Veja o exemplo do modelo Many-to-many relationship para um exemplo completo.

ManyToManyFieldcampos também aceitam um número de argumentos extras que são explicados na referência de campo do modelo . Essas opções ajudam a de nir como o
relacionamento deve funcionar; todos são opcionais.

Campos extras em relacionamentos muitos-para-muitos


Idioma: en
Quando você está lidando apenas com relacionamentos muitos-para-muitos simples, como misturar e combinar pizzas e coberturas, um padrão ManyToManyFieldé tudo que você
precisa. No entanto, às vezes, você pode precisar associar dados ao relacionamento entre dois modelos.
Versão da documentação: 2.1
Por exemplo, considere o caso de um aplicativo rastreando os grupos musicais aos quais os músicos pertencem. Há um relacionamento muitos-para-muitos entre uma pessoa e os
grupos dos quais ela é membro, portanto, você poderia usar um ManyToManyFieldpara representar esse relacionamento. No entanto, há muitos detalhes sobre a associação que você
pode querer coletar, como a data em que a pessoa ingressou no grupo.

Para estas situações, o Django permite que você especi que o modelo que será usado para governar o relacionamento muitos-para-muitos. Você pode então colocar campos extras no
modelo intermediário. O modelo intermediário está associado ao ManyToManyFielduso do throughargumento para apontar para o modelo que atuará como intermediário. Para
nosso exemplo de músico, o código seria algo como isto:

from django.db import models

class Person(models.Model):
name = models.CharField(max_length=128)

def __str__(self):
return self.name

class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')

def __str__(self):
return self.name

class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)

Quando você con gura o modelo intermediário, especi ca explicitamente as chaves estrangeiras para os modelos que estão envolvidos no relacionamento muitos-para-muitos. Esta
declaração explícita de ne como os dois modelos estão relacionados.

Existem algumas restrições no modelo intermediário:

Seu modelo intermediário deve conter uma - e apenas uma - chave estrangeira para o modelo de origem (isso seria Groupem nosso exemplo), ou você deve especi car
explicitamente as chaves estrangeiras que o Django deve usar para o relacionamento usando ManyToManyField.through_fields. Se você tiver mais de uma chave estrangeira
e through_fieldsnão for especi cado, um erro de validação será gerado. Uma restrição semelhante se aplica à chave estrangeira para o modelo de destino (isso seria
Personno nosso exemplo).

Para um modelo que possui um relacionamento muitos-para-muitos com um modelo intermediário, duas chaves estrangeiras para o mesmo modelo são permitidas, mas elas serão
tratadas como os dois lados (diferentes) do relacionamento muitos-para-muitos. Se houver mais de duas chaves estrangeiras, você também deve especi car
through_fieldscomo acima ou um erro de validação será gerado.

Ao de nir um relacionamento muitos-para-muitos de um modelo para si mesmo, usando um modelo intermediário, você deve usar symmetrical=False(consulte a referência de
campo do modelo ).

Agora que você con gurou o seu ManyToManyFieldpara usar seu modelo intermediário ( Membershipneste caso), você está pronto para começar a criar alguns relacionamentos
muitos-para-muitos. Você faz isso criando instâncias do modelo intermediário:

>>> ringo = Person.objects.create(name="Ringo Starr")


>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
... date_joined=date(1962, 8, 16),
... invite_reason="Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>]>
>>> ringo.group_set.all()
<QuerySet [<Group: The Beatles>]>
>>> m2 = Membership.objects.create(person=paul, group=beatles,
... date_joined=date(1960, 8, 1),
... invite_reason="Wanted to form a band.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>

Ao contrário normais muitos-para-muitos campos, você não pode usar add(), create()ou set()para criar relacionamentos:

Idioma: en
>>> # The following statements will not work
>>> beatles.members.add(john)
>>> beatles.members.create(name="George Harrison") Versão da documentação: 2.1
>>> beatles.members.set([john, paul, ringo, george])
Por quê? Você não pode simplesmente criar um relacionamento entre a Persone a Group - você precisa especi car todos os detalhes para o relacionamento requerido pelo
Membershipmodelo. Os simples add, createe chamadas de atribuição não fornecem uma maneira de especi car esse detalhe extra. Como resultado, eles são desativados para
relacionamentos muitos-para-muitos que usam um modelo intermediário. A única maneira de criar esse tipo de relacionamento é criar instâncias do modelo intermediário.

O remove()método está desativado por motivos semelhantes. Por exemplo, se a tabela personalizada através do modelo intermediário não forçar a exclusividade do par, uma chamada
não fornecerá informações su cientes sobre qual instância do modelo intermediário deve ser excluída:(model1, model2)remove()

>>> Membership.objects.create(person=ringo, group=beatles,


... date_joined=date(1968, 9, 4),
... invite_reason="You've been gone for a month and we miss you.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]>
>>> # This will not work because it cannot tell which membership to remove
>>> beatles.members.remove(ringo)

No entanto, o clear() método pode ser usado para remover todos os relacionamentos muitos para muitos de uma instância:

>>> # Beatles have broken up


>>> beatles.members.clear()
>>> # Note that this deletes the intermediate model instances
>>> Membership.objects.all()
<QuerySet []>

Depois de estabelecer as relações muitos-para-muitos, criando instâncias do seu modelo intermediário, você poderá emitir consultas. Assim como com relacionamentos muitos-para-
muitos normais, você pode consultar usando os atributos do modelo muitos-para-muitos:

# Find all the groups with a member whose name starts with 'Paul'
>>> Group.objects.filter(members__name__startswith='Paul')
<QuerySet [<Group: The Beatles>]>

Como você está usando um modelo intermediário, você também pode consultar seus atributos:

# Find all the members of the Beatles that joined after 1 Jan 1961
>>> Person.objects.filter(
... group__name='The Beatles',
... membership__date_joined__gt=date(1961,1,1))
<QuerySet [<Person: Ringo Starr]>

Se você precisar acessar as informações de uma associação, poderá fazer isso consultando diretamente o Membershipmodelo:

>>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)


>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'

Outra maneira de acessar as mesmas informações é consultando o relacionamento reverso de muitos para muitos de um Personobjeto:

>>> ringos_membership = ringo.membership_set.get(group=beatles)


>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason Idioma: en

'Needed a new drummer.'

Versão da documentação: 2.1


Relações um-para-um

Para de nir um relacionamento um-para-um, use OneToOneField. Você o usa como qualquer outro Fieldtipo: incluindo-o como um atributo de classe do seu modelo.

Isso é mais útil na chave primária de um objeto quando esse objeto “estende” outro objeto de alguma forma.

OneToOneField requer um argumento posicional: a classe à qual o modelo está relacionado.

Por exemplo, se você estivesse criando um banco de dados de “lugares”, você criaria um material padrão como endereço, número de telefone etc. no banco de dados. Então, se você
quisesse construir um banco de dados de restaurantes no topo dos lugares, em vez de se repetir e replicar esses campos no Restaurantmodelo, você poderia Restaurantter um
OneToOneFielda Place(porque um restaurante “é um” lugar; você normalmente usaria herança , o que envolve uma relação implícita de um para um).

Assim como ForeignKey, um relacionamento recursivo pode ser de nido e referências a modelos ainda inde nidos podem ser feitas.

Veja também

 Veja o exemplo do modelo de relacionamento Um-para-um para um exemplo completo.

OneToOneFieldcampos também aceitam um parent_linkargumento opcional .

OneToOneFieldclasses usadas para se tornar automaticamente a chave primária em um modelo. Isso não é mais verdade (embora você possa passar manualmente o
primary_keyargumento, se quiser). Assim, agora é possível ter vários campos do tipo OneToOneFieldem um único modelo.

Modelos através de arquivos


É perfeitamente correto relacionar um modelo a outro de outro aplicativo. Para fazer isso, importe o modelo relacionado na parte superior do arquivo em que seu modelo está de nido.
Então, basta se referir à outra classe de modelo sempre que necessário. Por exemplo:

from django.db import models


from geography.models import ZipCode

class Restaurant(models.Model):
# ...
zip_code = models.ForeignKey(
ZipCode,
on_delete=models.SET_NULL,
blank=True,
null=True,
)

Restrições de nome de campo


O Django coloca apenas duas restrições nos nomes dos campos do modelo:

1. Um nome de campo não pode ser uma palavra reservada do Python, porque isso resultaria em um erro de sintaxe Python. Por exemplo:

class Example(models.Model):
pass = models.IntegerField() # 'pass' is a reserved word!

2. Um nome de campo não pode conter mais de um sublinhado em uma linha, devido à maneira como a sintaxe de consulta de consulta do Django funciona. Por exemplo:

class Example(models.Model):
foo__bar = models.IntegerField() # 'foo__bar' has two underscores!

Idioma: en

No entanto, essas limitações podem ser contornadas, porque o nome do seu campo não precisa necessariamente corresponder ao nome da coluna do seu banco de dados. Veja a
db_columnopção. Versão da documentação: 2.1
As palavras reservadas SQL, como join, whereou select, são permitidas como nomes de campos de modelo, porque o Django escapa de todos os nomes de tabela de banco de
dados e nomes de coluna em cada consulta SQL subjacente. Ele usa a sintaxe de cotação do seu mecanismo de banco de dados especí co.

Tipos de campos personalizados


Se um dos campos de modelo existentes não puder ser usado para atender às suas nalidades, ou se você quiser tirar vantagem de alguns tipos de coluna de banco de dados menos
comuns, poderá criar sua própria classe de campo. A cobertura total da criação de seus próprios campos é fornecida em Escrevendo campos de modelo personalizado .

Metaopções
Dê o seu modelo de metadados usando um interior , assim:class Meta

from django.db import models

class Ox(models.Model):
horn_length = models.IntegerField()

class Meta:
ordering = ["horn_length"]
verbose_name_plural = "oxen"

Metadados de modelo são “qualquer coisa que não seja um campo”, como opções de ordenação ( ordering), nome da tabela de banco de dados ( db_table) ou nomes singulares e
plurais legíveis para humanos ( verbose_namee verbose_name_plural). Nenhum é necessário, e adicionar a um modelo é completamente opcional.class Meta

Uma lista completa de todas as Metaopções possíveis pode ser encontrada na referência de opção do modelo .

Atributos do modelo

objects
O atributo mais importante de um modelo é o Manager. É a interface através da qual as operações de consulta de banco de dados são fornecidas aos modelos do Django e são usadas
para recuperar as instâncias do banco de dados. Se nenhum personalizado Managerestiver de nido, o nome padrão será objects. Os gerentes são acessíveis apenas por meio de
classes de modelo, não das instâncias do modelo.

Métodos de modelo
De na métodos personalizados em um modelo para adicionar funcionalidade "nível de linha" personalizada aos seus objetos. Enquanto os Managermétodos se destinam a fazer coisas
"em toda a mesa", os métodos de modelo devem atuar em uma instância de modelo especí ca.

Essa é uma técnica valiosa para manter a lógica de negócios em um só lugar - o modelo.

Por exemplo, esse modelo possui alguns métodos personalizados:

from django.db import models

class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_date = models.DateField()

def baby_boomer_status(self):
"Returns the person's baby-boomer status."
import datetime
if self.birth_date < datetime.date(1945, 8, 1):
return "Pre-boomer"
elif self.birth_date < datetime.date(1965, 1, 1):
return "Baby boomer"
else:
return "Post-boomer"
Idioma: en

@property
def full_name(self): Versão da documentação: 2.1
"Returns the person's full name."
return '%s %s' % (self.first_name, self.last_name)
O último método neste exemplo é uma propriedade .

A referência de instância do modelo tem uma lista completa de métodos fornecidos automaticamente para cada modelo . Você pode substituir a maioria deles - veja abaixo os métodos
de modelos prede nidos , mas há alguns que você quase sempre quer de nir:

__str__()

Um "método mágico" do Python que retorna uma representação de string de qualquer objeto. Isso é o que Python e Django usarão sempre que uma instância de modelo precisar ser
coagida e exibida como uma string simples. Mais notavelmente, isso acontece quando você exibe um objeto em um console interativo ou no admin.

Você sempre desejará de nir esse método; o padrão não é muito útil.

get_absolute_url()

Isso diz ao Django como calcular o URL de um objeto. O Django usa isso em sua interface administrativa, e sempre que precisar descobrir um URL para um objeto.

Qualquer objeto que tenha um URL que o identi que exclusivamente deve de nir esse método.

Substituindo métodos modelo prede nidos


Há outro conjunto de métodos de modelo que encapsula um monte de comportamento de banco de dados que você deseja personalizar. Em particular, muitas vezes você vai querer
mudar o caminho save()e delete()trabalhar.

Você está livre para substituir esses métodos (e qualquer outro método de modelo) para alterar o comportamento.

Um caso de uso clássico para substituir os métodos internos é se você deseja que algo aconteça sempre que você salvar um objeto. Por exemplo (consulte save()a documentação
dos parâmetros que aceita):

from django.db import models

class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()

def save(self, *args, **kwargs):


do_something()
super().save(*args, **kwargs) # Call the "real" save() method.
do_something_else()

Você também pode evitar salvar:

from django.db import models

class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()

def save(self, *args, **kwargs):


if self.name == "Yoko Ono's blog":
return # Yoko shall never have her own blog!
else:
super().save(*args, **kwargs) # Call the "real" save() method.

É importante lembrar de chamar o método da superclasse - esse é o negócio - para garantir que o objeto ainda seja salvo no banco de dados. Se você esquecer de chamar o método da
superclasse, o comportamento padrão não acontecerá e o banco de dados não será afetado.super().save(*args, **kwargs)

Também é importante que você passe pelos argumentos que podem ser passados para o método de modelo - é o que o bit faz. O Django irá, de tempos em tempos, estender os
recursos dos métodos de modelo embutidos, adicionando novos argumentos. Se você usar em suas de nições de método, terá a garantia de que seu código suportará automaticamente
esses argumentos quando eles forem adicionados.*args, **kwargs*args, **kwargs

Métodos de modelo substituídos não são chamados em operações em massa

 Observe que o delete()método para um objeto não é necessariamente chamado ao excluir objetos em massa usando um QuerySet ou como resultado de um .
Para garantir que a lógica de exclusão personalizada seja executada, você pode usar e / ou sinais.cascading deletepre_deletepost_delete

Infelizmente, não há uma solução alternativa quando creatingou updatingobjetos em massa, uma vez que nenhum save(), pre_savee post_savesão
Idioma: en
chamados.

Versão da documentação: 2.1


Executando SQL customizado
Outro padrão comum é escrever instruções SQL personalizadas em métodos de modelo e métodos de nível de módulo. Para obter mais detalhes sobre o uso de SQL bruto, consulte a
documentação sobre o uso de SQL bruto .

Herança de modelo
A herança de modelo no Django funciona quase de maneira idêntica à forma como a herança de classe normal funciona em Python, mas os princípios básicos no início da página ainda
devem ser seguidos. Isso signi ca que a classe base deve ser subclasse django.db.models.Model.

A única decisão a ser tomada é se você deseja que os modelos pai sejam modelos por direito próprio (com suas próprias tabelas de banco de dados) ou se os pais são apenas
detentores de informações comuns que só serão visíveis por meio dos modelos lhos.

Existem três estilos de herança que são possíveis no Django.

1. Muitas vezes, você só vai querer usar a classe pai para armazenar informações que você não deseja digitar em cada modelo lho. Esta classe nunca será usada isoladamente,
então classes base abstratas são o que você procura.

2. Se você estiver subclassi cando um modelo existente (talvez algo de outro aplicativo completamente) e quiser que cada modelo tenha sua própria tabela de banco de dados,
a herança de várias tabelas é o caminho a ser seguido.

3. Finalmente, se você quiser modi car apenas o comportamento em nível de Python de um modelo, sem alterar os campos dos modelos de forma alguma, poderá usar os
modelos Proxy .

Classes base abstratas


As classes base abstratas são úteis quando você deseja colocar algumas informações comuns em vários outros modelos. Você escreve sua classe base e coloca abstract=Truena
classe Meta . Este modelo não será usado para criar qualquer tabela de banco de dados. Em vez disso, quando é usado como uma classe base para outros modelos, seus campos serão
adicionados àqueles da classe lha.

Um exemplo:

from django.db import models

class CommonInfo(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()

class Meta:
abstract = True

class Student(CommonInfo):
home_group = models.CharField(max_length=5)

O Studentmodelo terá três campos: name, agee home_group. O CommonInfomodelo não pode ser usado como um modelo normal do Django, já que é uma classe base abstrata. Ele
não gera uma tabela de banco de dados nem possui um gerenciador e não pode ser instanciado ou salvo diretamente.

Campos herdados de classes base abstratas podem ser substituídos por outro campo ou valor, ou serem removidos com None.

Para muitos usos, esse tipo de herança de modelo será exatamente o que você deseja. Ele fornece uma maneira de fatorar informações comuns no nível do Python, enquanto ainda cria
apenas uma tabela de banco de dados por modelo lho no nível do banco de dados.

Metaherança

Quando uma classe base abstrata é criada, o Django torna qualquer classe interna Meta declarada na classe base como um atributo. Se uma classe lha não declarar sua própria classe
Meta , ela herdará o Meta do pai . Se o lho quiser estender a classe Meta do pai , ele poderá subclassá-lo. Por exemplo:

from django.db import models

class CommonInfo(models.Model):
# ...
class Meta:
abstract = True
ordering = ['name']

class Student(CommonInfo): Idioma: en


# ...
class Meta(CommonInfo.Meta):
db_table = 'student_info' Versão da documentação: 2.1
O Django faz um ajuste na classe Meta de uma classe base abstrata: antes de instalar o atributo Meta , ele de ne abstract=False. Isso signi ca que lhos de classes base abstratas
não se tornam automaticamente classes abstratas. Claro, você pode criar uma classe base abstrata que herda de outra classe base abstrata. Você só precisa lembrar de de nir
explicitamente a abstract=Truecada vez.

Alguns atributos não farão sentido em incluir na classe Meta de uma classe base abstrata. Por exemplo, incluir db_tablesigni caria que todas as classes lho (aquelas que não
especi cam seu próprio Meta ) usariam a mesma tabela de banco de dados, o que quase certamente não é o que você deseja.

Tenha cuidado com related_namee related_query_name

Se você estiver usando related_nameou related_query_nameem um ForeignKeyou ManyToManyField, deverá sempre especi car um nome reverso exclusivo e um nome de
consulta para o campo. Isso normalmente causaria um problema nas classes base abstratas, uma vez que os campos dessa classe são incluídos em cada uma das classes lhas, com
exatamente os mesmos valores para os atributos (incluindo related_namee related_query_name) de cada vez.

Para contornar esse problema, quando você está usando related_nameou related_query_nameem uma classe base abstrata (somente), parte do valor deve conter '%
(app_label)s'e '%(class)s'.

'%(class)s' é substituído pelo nome com caixa inferior da classe lha na qual o campo é usado.

'%(app_label)s'é substituído pelo nome de caixa inferior do aplicativo em que a classe lha está contida. Cada nome de aplicativo instalado deve ser exclusivo e os nomes de
classe de modelo dentro de cada aplicativo também devem ser exclusivos; portanto, o nome resultante será diferente.

Por exemplo, dado um aplicativo common/models.py:

from django.db import models

class Base(models.Model):
m2m = models.ManyToManyField(
OtherModel,
related_name="%(app_label)s_%(class)s_related",
related_query_name="%(app_label)s_%(class)ss",
)

class Meta:
abstract = True

class ChildA(Base):
pass

class ChildB(Base):
pass

Juntamente com outro aplicativo rare/models.py:

from common.models import Base

class ChildB(Base):
pass

O nome reverso do common.ChildA.m2mcampo será common_childa_relatede o nome da consulta inversa será common_childas. O nome reverso do
common.ChildB.m2mcampo será common_childb_relatede o nome da consulta inversa será common_childbs. Finalmente, o nome reverso do rare.ChildB.m2mcampo será
rare_childb_relatede o nome da consulta inversa será rare_childbs. Cabe a você como você usa o '%(class)s'e '%(app_label)s'parte para construir o seu nome
relacionado ou nome de consulta relacionado, mas se você esquecer de usá-lo, o Django irá gerar erros quando você executar as veri cações do sistema (ou executar migrate).

Se você não especi car um related_name atributo para um campo em uma classe base abstrata, o nome reverso padrão será o nome da classe lha seguido por '_set', como
normalmente seria se você tivesse declarado o campo diretamente na classe lha. . Por exemplo, no código acima, se o related_name atributo foi omitido, o nome reverso do
m2mcampo estaria childa_setno ChildAcaso e childb_setno ChildB campo.

Herança de várias tabelas


O segundo tipo de herança de modelo suportado pelo Django é quando cada modelo na hierarquia é um modelo sozinho. Cada modelo corresponde à sua própria tabela de banco de
dados e pode ser consultado e criado individualmente. O relacionamento de herança introduz links entre o modelo lho e cada um de seus pais (por meio de um criado automaticamente
OneToOneField). Por exemplo:

Idioma: en

Versão da documentação: 2.1


from django.db import models

class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)

class Restaurant(Place):
serves_hot_dogs = models.BooleanField(default=False)
serves_pizza = models.BooleanField(default=False)

Todos os campos de Placetambém estarão disponíveis Restaurant, embora os dados residam em uma tabela de banco de dados diferente. Então, ambos são possíveis:

>>> Place.objects.filter(name="Bob's Cafe")


>>> Restaurant.objects.filter(name="Bob's Cafe")

Se você tiver um Placeque também é a Restaurant, você pode obter do Placeobjeto para o Restaurantobjeto usando a versão em minúscula do nome do modelo:

>>> p = Place.objects.get(id=12)
# If p is a Restaurant object, this will give the child class:
>>> p.restaurant
<Restaurant: ...>

No entanto, se pno exemplo acima não foi um Restaurant(ele foi criado diretamente como um Placeobjeto ou era o pai de alguma outra classe), referindo-se a
p.restaurantsuscitar uma Restaurant.DoesNotExist exceção.

O criado automaticamente OneToOneFieldem Restaurantque links para se Placeparece com isso:

place_ptr = models.OneToOneField(
Place, on_delete=models.CASCADE,
parent_link=True,
)

Você pode substituir esse campo declarando o seu próprio OneToOneFieldcom parent_link=Trueon Restaurant.

Metae herança de múltiplas tabelas

Na situação de herança de várias tabelas, não faz sentido que uma classe lha herde da classe Meta de seus pais . Todas as opções Meta já foram aplicadas à classe pai e aplicá-las
novamente normalmente levaria apenas a um comportamento contraditório (isso está em contraste com o caso da classe base abstrata, em que a classe base não existe por si só).

Portanto, um modelo lho não tem acesso à classe Meta do pai . No entanto, há alguns casos limitados em que o lho herda o comportamento do pai: se o lho não especi car um
orderingatributo ou um get_latest_byatributo, ele herdará esses do pai.

Se o pai tiver uma ordem e você não quiser que a criança tenha uma ordem natural, você poderá desabilitá-la explicitamente:

class ChildModel(ParentModel):
# ...
class Meta:
# Remove parent's ordering effect
ordering = []

Herança e relações reversas

Como a herança de várias tabelas usa um implícito OneToOneFieldpara vincular o lho e o pai, é possível passar do pai para o lho, como no exemplo acima. No entanto, isso usa o
nome que é o related_namevalor padrão para ForeignKeye ManyToManyFieldrelações. Se você estiver colocando esses tipos de relações em uma subclasse do modelo pai,
Idioma: en
deverá especi car o related_name atributo em cada um desses campos. Se você esquecer, o Django irá gerar um erro de validação.

Por exemplo, usando a Placeclasse acima novamente, vamos criar outra subclasse com um ManyToManyField: Versão da documentação: 2.1
class Supplier(Place):
customers = models.ManyToManyField(Place)

Isso resulta no erro:

Reverse query name for 'Supplier.customers' clashes with reverse query


name for 'Supplier.place_ptr'.

HINT: Add or change a related_name argument to the definition for


'Supplier.customers' or 'Supplier.place_ptr'.

Adicionando related_nameao customerscampo da seguinte iria resolver o erro: .models.ManyToManyField(Place, related_name='provider')

Especi cando o campo de link pai

Como mencionado, o Django irá criar automaticamente uma OneToOneFieldligação da sua classe lha de volta para qualquer modelo pai não abstrato. Se você quiser controlar o
nome do atributo que está ligando de volta ao pai, você pode criar o seu próprio OneToOneFielde de nir parent_link=True para indicar que o seu campo é o link de volta para a
classe pai.

Modelos de proxy
Ao usar herança de várias tabelas , uma nova tabela de banco de dados é criada para cada subclasse de um modelo. Geralmente, esse é o comportamento desejado, pois a subclasse
precisa de um local para armazenar quaisquer campos de dados adicionais que não estejam presentes na classe base. Às vezes, no entanto, você só deseja alterar o comportamento do
Python de um modelo - talvez para alterar o gerenciador padrão ou adicionar um novo método.

É para isso que serve a herança do modelo de proxy: criar um proxy para o modelo original. Você pode criar, excluir e atualizar instâncias do modelo de proxy e todos os dados serão
salvos como se você estivesse usando o modelo original (não-proxy). A diferença é que você pode alterar coisas como a ordenação de modelos padrão ou o gerenciador padrão no
proxy, sem precisar alterar o original.

Modelos proxy são declarados como modelos normais. Você diz ao Django que é um modelo de proxy de nindo o proxyatributo da Metaclasse True.

Por exemplo, suponha que você queira adicionar um método ao Personmodelo. Você pode fazer assim:

from django.db import models

class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)

class MyPerson(Person):
class Meta:
proxy = True

def do_something(self):
# ...
pass

A MyPersonclasse opera na mesma tabela de banco de dados que sua Personclasse pai . Em particular, quaisquer novas instâncias de Persontambém estarão acessíveis MyPerson,
e vice-versa:

>>> p = Person.objects.create(first_name="foobar")
>>> MyPerson.objects.get(first_name="foobar")
<MyPerson: foobar>

Você também pode usar um modelo de proxy para de nir uma ordem padrão diferente em um modelo. Você pode nem sempre querer pedir o Personmodelo, mas pedir regularmente
pelo last_nameatributo ao usar o proxy. Isso é facil:
Idioma: en

Versão da documentação: 2.1


class OrderedPerson(Person):
class Meta:
ordering = ["last_name"]
proxy = True

Agora, as Personconsultas normais serão desordenadas e as OrderedPersonconsultas serão ordenadas por last_name.

Os modelos de proxy herdam os Metaatributos da mesma forma que os modelos normais .

QuerySets ainda retorna o modelo que foi solicitado

Não há como o Django retornar, digamos, um MyPersonobjeto sempre que você consultar Personobjetos. Um queryset para Personobjetos retornará esses tipos de objetos. O ponto
principal dos objetos proxy é que o código baseado no original Personos usará e seu próprio código poderá usar as extensões que você incluiu (que nenhum outro código está
con ando). Não é uma maneira de substituir o Person(ou qualquer outro) modelo em qualquer lugar com algo de sua própria criação.

Restrições da classe base

Um modelo de proxy deve herdar exatamente de uma classe de modelo não abstrata. Você não pode herdar de vários modelos não abstratos, pois o modelo de proxy não fornece
nenhuma conexão entre as linhas nas diferentes tabelas do banco de dados. Um modelo de proxy pode herdar de qualquer número de classes de modelo abstratas, desde que elas não
de nam nenhum campo de modelo. Um modelo de proxy também pode herdar de qualquer número de modelos de proxy que compartilham uma classe pai comum não abstrata.

Gerenciadores de modelos de proxy

Se você não especi car nenhum gerenciador de modelos em um modelo de proxy, ele herdará os gerentes de seus pais modelo. Se você de nir um gerenciador no modelo de proxy, ele
se tornará o padrão, embora todos os gerenciadores de nidos nas classes pai ainda estejam disponíveis.

Continuando nosso exemplo a partir de cima, você pode alterar o gerenciador padrão usado ao consultar o Personmodelo da seguinte forma:

from django.db import models

class NewManager(models.Manager):
# ...
pass

class MyPerson(Person):
objects = NewManager()

class Meta:
proxy = True

Se você quiser adicionar um novo gerenciador ao Proxy, sem substituir o padrão existente, poderá usar as técnicas descritas na documentação do gerenciador customizado : crie uma
classe base contendo os novos gerenciadores e herde a seguinte após a classe base primária:

# Create an abstract class for the new manager.


class ExtraManagers(models.Model):
secondary = NewManager()

class Meta:
abstract = True

class MyPerson(Person, ExtraManagers):


class Meta:
proxy = True

Você provavelmente não precisará fazer isso com muita frequência, mas, quando isso acontecer, é possível.

Diferenças entre herança de proxy e modelos não gerenciados

A herança do modelo de proxy pode parecer bastante semelhante à criação de um modelo não gerenciado, usando o managedatributo na Metaclasse de um modelo . Idioma: en

Com uma con guração cuidadosa, Meta.db_tablevocê pode criar um modelo não gerenciado que ilumine um modelo existente e adicione métodos Python a ele. No entanto, isso
seria muito repetitivo e frágil, pois você precisa manter as duas cópias sincronizadas se zer alguma alteração. Versão da documentação: 2.1
Por outro lado, os modelos de proxy devem se comportar exatamente como o modelo para o qual estão se aproximando. Eles estão sempre em sincronia com o modelo pai, pois
herdam diretamente seus campos e gerentes.

As regras gerais são:

1. Se você estiver espelhando um modelo existente ou uma tabela de banco de dados e não desejar todas as colunas da tabela de banco de dados original, use
Meta.managed=False. Essa opção é normalmente útil para modelar visualizações de banco de dados e tabelas que não estão sob o controle do Django.

2. Se você deseja alterar o comportamento de um modelo somente para Python, mas mantenha todos os mesmos campos do original, use Meta.proxy=True. Isso con gura
as coisas para que o modelo de proxy seja uma cópia exata da estrutura de armazenamento do modelo original quando os dados são salvos.

Herança múltipla
Assim como na subclasse do Python, é possível que um modelo do Django herde de vários modelos pais. Tenha em mente que as regras normais de resolução de nomes do Python se
aplicam. A primeira classe base na qual um nome especí co (por exemplo, Meta ) aparece será aquele que é usado; por exemplo, isso signi ca que se vários pais contiverem uma classe
Meta , somente a primeira será usada e todas as outras serão ignoradas.

Geralmente, você não precisará herdar de vários pais. O principal caso de uso em que isso é útil é para classes “mix-in”: adicionando um campo ou método extra especí co a cada classe
que herda o mix-in. Tente manter suas hierarquias de herança tão simples e diretas quanto possível, para que você não tenha que se esforçar para descobrir de onde vem uma
determinada informação.

Observe que a herança de vários modelos que possuem um idcampo de chave primária comum gerará um erro. Para usar corretamente a herança múltipla, você pode usar um explícito
AutoFieldnos modelos base:

class Article(models.Model):
article_id = models.AutoField(primary_key=True)
...

class Book(models.Model):
book_id = models.AutoField(primary_key=True)
...

class BookReview(Book, Article):


pass

Ou use um ancestral comum para segurar o AutoField. Isso requer o uso de um explícito OneToOneFieldde cada modelo pai para o ancestral comum para evitar um con ito entre os
campos que são gerados automaticamente e herdados pelo lho:

class Piece(models.Model):
pass

class Article(Piece):
article_piece = models.OneToOneField(Piece, on_delete=models.CASCADE, parent_link=True)
...

class Book(Piece):
book_piece = models.OneToOneField(Piece, on_delete=models.CASCADE, parent_link=True)
...

class BookReview(Book, Article):


pass

O nome do campo "esconder" não é permitido


Na herança de classe Python normal, é permitido que uma classe lha substitua qualquer atributo da classe pai. No Django, isso geralmente não é permitido para campos de modelo. Se
uma classe base de modelo não abstrata tiver um campo chamado author, você não poderá criar outro campo de modelo ou de nir um atributo chamado authorem qualquer classe
que herda dessa classe base.

Essa restrição não se aplica a campos de modelo herdados de um modelo abstrato. Tais campos podem ser substituídos por outro campo ou valor, ou serem removidos pela
con guração .field_name = None

Idioma: en
Aviso

 Os gerentes de modelo são herdados de classes base abstratas. Substituir um campo herdado que é referenciado por um herdado Managerpode causar erros
sutis. Veja gerentes personalizados e herança de modelos . Versão da documentação: 2.1
Nota

 Alguns campos de nem atributos adicionais sobre o modelo, por exemplo, um ForeignKeyde ne um atributo adicional com _idanexado ao nome do campo,
assim como related_namee related_query_nameno modelo estrangeiro.

Esses atributos extras não podem ser substituídos, a menos que o campo que o de ne seja alterado ou removido para que ele não de na mais o atributo extra.

Substituir campos em um modelo pai leva a di culdades em áreas como inicializar novas instâncias (especi cando em qual campo está sendo inicializado Model.__init__) e
serialização. Esses são recursos com os quais a herança de classe Python normal não precisa lidar da mesma maneira, então a diferença entre a herança de modelo do Django e a
herança de classe Python não é arbitrária.

Essa restrição se aplica apenas a atributos que são Fieldinstâncias. Atributos normais do Python podem ser substituídos se você desejar. Também se aplica apenas ao nome do
atributo como o Python o vê: se você especi car manualmente o nome da coluna do banco de dados, poderá ter o mesmo nome de coluna aparecendo em um modelo lho e um
ancestral para herança de várias tabelas (são colunas em duas tabelas de banco de dados diferentes).

O Django aumentará FieldErrorse você substituir qualquer campo de modelo em qualquer modelo ancestral.

Organizando modelos em um pacote


O comando cria uma estrutura de aplicativo que inclui um arquivo. Se você tiver muitos modelos, organizá-los em arquivos separados pode ser útil.manage.py startappmodels.py

Para fazer isso, crie um modelspacote. Remova models.pye crie um myapp/models/diretório com um __init__.pyarquivo e os arquivos para armazenar seus modelos. Você deve
importar os modelos no __init__.pyarquivo.

Por exemplo, se você tivesse organic.pye synthetic.pyno models diretório:

myapp / models / __ init__.py 

from .organic import Person


from .synthetic import Robot

A importação explícita de cada modelo em vez de usar tem as vantagens de não confundir o namespace, tornando o código mais legível e mantendo úteis as ferramentas de análise de
código.from .models import *

Veja também

 A referência de modelos
Abrange todas as APIs relacionadas ao modelo, incluindo campos de modelo, objetos relacionados e QuerySet.

 Modelos e bancos de dados Fazendo consultas 

Saber mais

Sobre o Django

Começando com o Django

Organização da equipe
Idioma: en
Fundação de Software Django

Código de conduta Versão da documentação: 2.1

Declaração de diversidade
Se envolver

Junte-se a um grupo

Contribua para o Django

Envie um bug

Relatar um problema de segurança

Siga-nos

GitHub

Twitter

Notícias RSS

Lista de discussão de usuários do Django

© 2005-2019 Django Software Foundation e colaboradores individuais. Django é uma marca registrada da Django Software Foundation.

Idioma: en

Versão da documentação: 2.1

You might also like